diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 1778b2a6..453aad70 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.0.2" + ".": "4.0.3" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 68430064..154ee8e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,23 @@ # Change Log +## [4.0.3](https://github.com/ruby-git/ruby-git/compare/v4.0.2...v4.0.3) (2025-07-08) + + +### Bug Fixes + +* Correct the deprecation horizon for Git deprecations ([b7b7f38](https://github.com/ruby-git/ruby-git/commit/b7b7f38ccb88ba719e8ea7cb3fea14474b19a00c)) +* Fix Rubocop Layout/EmptyLinesAroundClassBody offense ([1de27da](https://github.com/ruby-git/ruby-git/commit/1de27daabed18b47a42539fe69b735d8ee90cbbb)) +* Internally create a Stash with non-deprecated initializer args ([8b9b9e2](https://github.com/ruby-git/ruby-git/commit/8b9b9e2f3b3fa525973785f642331317ade35936)) +* Report correct line number in deprecation warnings ([cca0deb](https://github.com/ruby-git/ruby-git/commit/cca0debb4166c809af76f9dc586e4fd06e142d44)) +* Un-deprecate Git::Diff methods ([761b6ff](https://github.com/ruby-git/ruby-git/commit/761b6ffcd363f4329a9cbafbf1379513a19ff174)) + + +### Other Changes + +* Make tests that emit a deprecation warning fail ([7e211d7](https://github.com/ruby-git/ruby-git/commit/7e211d7b2b7cc8d9da4a860361bef52280a5e73b)) +* Update all tests to not use deprecated features ([33ab0e2](https://github.com/ruby-git/ruby-git/commit/33ab0e255e229e22d84b14a4d4f5fb829c1fe37c)) + ## [4.0.2](https://github.com/ruby-git/ruby-git/compare/v4.0.1...v4.0.2) (2025-07-08) diff --git a/lib/git.rb b/lib/git.rb index 638b77d8..e23e2a07 100644 --- a/lib/git.rb +++ b/lib/git.rb @@ -4,7 +4,7 @@ require 'active_support/deprecation' module Git - Deprecation = ActiveSupport::Deprecation.new('3.0', 'Git') + Deprecation = ActiveSupport::Deprecation.new('5.0.0', 'Git') end require 'git/author' diff --git a/lib/git/diff.rb b/lib/git/diff.rb index c9770e81..aad1b712 100644 --- a/lib/git/diff.rb +++ b/lib/git/diff.rb @@ -38,38 +38,31 @@ def each(&) @full_diff_files.map { |file| file[1] }.each(&) end + def size + stats_provider.total[:files] + end + # # DEPRECATED METHODS # def name_status - Git::Deprecation.warn('Git::Diff#name_status is deprecated. Use Git::Base#diff_path_status instead.') path_status_provider.to_h end - def size - Git::Deprecation.warn('Git::Diff#size is deprecated. Use Git::Base#diff_stats(...).total[:files] instead.') - stats_provider.total[:files] - end - def lines - Git::Deprecation.warn('Git::Diff#lines is deprecated. Use Git::Base#diff_stats(...).lines instead.') stats_provider.lines end def deletions - Git::Deprecation.warn('Git::Diff#deletions is deprecated. Use Git::Base#diff_stats(...).deletions instead.') stats_provider.deletions end def insertions - Git::Deprecation.warn('Git::Diff#insertions is deprecated. Use Git::Base#diff_stats(...).insertions instead.') stats_provider.insertions end def stats - Git::Deprecation.warn('Git::Diff#stats is deprecated. Use Git::Base#diff_stats instead.') - # CORRECTED: Re-create the original hash structure for backward compatibility { files: stats_provider.files, total: stats_provider.total diff --git a/lib/git/log.rb b/lib/git/log.rb index c5b3c6da..644322d9 100644 --- a/lib/git/log.rb +++ b/lib/git/log.rb @@ -90,28 +90,56 @@ def execute # @deprecated Use {#execute} and call `each` on the result. def each(&) - deprecate_and_run + Git::Deprecation.warn( + 'Calling Git::Log#each is deprecated. Call #execute and then #each on the result object.' + ) + run_log_if_dirty @commits.each(&) end # @deprecated Use {#execute} and call `size` on the result. def size - deprecate_and_run + Git::Deprecation.warn( + 'Calling Git::Log#size is deprecated. Call #execute and then #size on the result object.' + ) + run_log_if_dirty @commits&.size end # @deprecated Use {#execute} and call `to_s` on the result. def to_s - deprecate_and_run + Git::Deprecation.warn( + 'Calling Git::Log#to_s is deprecated. Call #execute and then #to_s on the result object.' + ) + run_log_if_dirty @commits&.map(&:to_s)&.join("\n") end # @deprecated Use {#execute} and call the method on the result. - %i[first last []].each do |method_name| - define_method(method_name) do |*args| - deprecate_and_run - @commits&.public_send(method_name, *args) - end + def first + Git::Deprecation.warn( + 'Calling Git::Log#first is deprecated. Call #execute and then #first on the result object.' + ) + run_log_if_dirty + @commits&.first + end + + # @deprecated Use {#execute} and call the method on the result. + def last + Git::Deprecation.warn( + 'Calling Git::Log#last is deprecated. Call #execute and then #last on the result object.' + ) + run_log_if_dirty + @commits&.last + end + + # @deprecated Use {#execute} and call the method on the result. + def [](index) + Git::Deprecation.warn( + 'Calling Git::Log#[] is deprecated. Call #execute and then #[] on the result object.' + ) + run_log_if_dirty + @commits&.[](index) end # @!endgroup @@ -131,13 +159,5 @@ def run_log_if_dirty @commits = log_data.map { |c| Git::Object::Commit.new(@base, c['sha'], c) } @dirty = false end - - def deprecate_and_run(method = caller_locations(1, 1)[0].label) - Git::Deprecation.warn( - "Calling Git::Log##{method} is deprecated. " \ - "Call #execute and then ##{method} on the result object." - ) - run_log_if_dirty - end end end diff --git a/lib/git/stashes.rb b/lib/git/stashes.rb index d3eb4cfc..abef5e8c 100644 --- a/lib/git/stashes.rb +++ b/lib/git/stashes.rb @@ -12,7 +12,7 @@ def initialize(base) @base.lib.stashes_all.each do |indexed_message| _index, message = indexed_message - @stashes.unshift(Git::Stash.new(@base, message, true)) + @stashes.unshift(Git::Stash.new(@base, message, save: true)) end end diff --git a/lib/git/version.rb b/lib/git/version.rb index bd22d777..0b43866a 100644 --- a/lib/git/version.rb +++ b/lib/git/version.rb @@ -3,5 +3,5 @@ module Git # The current gem version # @return [String] the current gem version. - VERSION = '4.0.2' + VERSION = '4.0.3' end diff --git a/tests/test_helper.rb b/tests/test_helper.rb index fb4ac4b3..aa42eedd 100644 --- a/tests/test_helper.rb +++ b/tests/test_helper.rb @@ -12,8 +12,19 @@ $stdout.sync = true $stderr.sync = true -# Silence deprecation warnings during tests -Git::Deprecation.behavior = :silence +# Make tests that emit a deprecation warning fail + +# Deprecation warnings should not be ignored. + +# This is important so that: +# * when a user sees a deprecation warning, they can be confident it is coming from +# their code and not this gem +# * test output is clean and does not contain noisey deprecation warnings + +# Tests whose purpose is to test that a deprecation warning is issued in the right +# circumstance should mock Git::Deprecation#warn to avoid raising an error. +# +Git::Deprecation.behavior = :raise module Test module Unit diff --git a/tests/units/test_base.rb b/tests/units/test_base.rb index 65c67637..9e818d86 100644 --- a/tests/units/test_base.rb +++ b/tests/units/test_base.rb @@ -88,11 +88,13 @@ def test_commit git.add('test_file_1') git.add('test_file_2') - base_commit_id = git.log[0].objectish + commits = git.log.execute + base_commit_id = commits[0].objectish git.commit('Test Commit') - original_commit_id = git.log[0].objectish + commits = git.log.execute + original_commit_id = commits[0].objectish create_file('test_commit/test_file_3', 'content test_file_3') @@ -100,8 +102,9 @@ def test_commit git.commit(nil, amend: true) - assert(git.log[0].objectish != original_commit_id) - assert(git.log[1].objectish == base_commit_id) + commits = git.log.execute + assert(commits[0].objectish != original_commit_id) + assert(commits[1].objectish == base_commit_id) end end end diff --git a/tests/units/test_commit_with_empty_message.rb b/tests/units/test_commit_with_empty_message.rb index 41645d27..8ef6d890 100755 --- a/tests/units/test_commit_with_empty_message.rb +++ b/tests/units/test_commit_with_empty_message.rb @@ -20,7 +20,8 @@ def test_with_allow_empty_message_option Dir.mktmpdir do |dir| git = Git.init(dir) git.commit('', { allow_empty: true, allow_empty_message: true }) - assert_equal(1, git.log.to_a.size) + commits = git.log.execute + assert_equal(1, commits.to_a.size) end end end diff --git a/tests/units/test_git_dir.rb b/tests/units/test_git_dir.rb index 31e583f3..77f9ae14 100644 --- a/tests/units/test_git_dir.rb +++ b/tests/units/test_git_dir.rb @@ -62,11 +62,13 @@ def test_git_dir_outside_work_tree # * the commit was added to the log # max_log_size = 100 - assert_equal(64, git.log(max_log_size).size) + commits = git.log(max_log_size).execute + assert_equal(64, commits.size) git.add(file) git.commit('This is a new commit') assert_equal(false, git.status.changed?(file)) - assert_equal(65, git.log(max_log_size).size) + commits = git.log(max_log_size).execute + assert_equal(65, commits.size) end end end diff --git a/tests/units/test_git_path.rb b/tests/units/test_git_path.rb index 40e25fd9..1d8a2311 100644 --- a/tests/units/test_git_path.rb +++ b/tests/units/test_git_path.rb @@ -9,18 +9,18 @@ def setup end def test_initalize_with_good_path_and_check_path - path = Git::Path.new(@git.index.to_s, true) + path = Git::Path.new(@git.index.to_s, must_exist: true) assert_equal @git.index.to_s, path.to_s end def test_initialize_with_bad_path_and_check_path assert_raises ArgumentError do - Git::Path.new('/this path does not exist', true) + Git::Path.new('/this path does not exist', must_exist: true) end end def test_initialize_with_bad_path_and_no_check - path = Git::Path.new('/this path does not exist', false) + path = Git::Path.new('/this path does not exist', must_exist: false) assert path.to_s.end_with?('/this path does not exist') assert(path.to_s.match(%r{^(?:[A-Z]:)?/this path does not exist$})) diff --git a/tests/units/test_index_ops.rb b/tests/units/test_index_ops.rb index 233673c8..c4c0aba4 100644 --- a/tests/units/test_index_ops.rb +++ b/tests/units/test_index_ops.rb @@ -94,9 +94,10 @@ def test_revert g.commit('second-commit') g.gcommit('HEAD') - commits = g.log(10_000).count + commits = g.log(10_000).execute g.revert(first_commit.sha) - assert_equal(commits + 1, g.log(10_000).count) + commits_after_revert = g.log(10_000).execute + assert_equal(commits.count + 1, commits_after_revert.count) assert(!File.exist?('test-file2')) end end diff --git a/tests/units/test_log.rb b/tests/units/test_log.rb index 75b3300b..f2219d78 100644 --- a/tests/units/test_log.rb +++ b/tests/units/test_log.rb @@ -11,103 +11,124 @@ def setup end def test_log_max_count_default - assert_equal(30, @git.log.size) + # Default max_count is 30 + commits = @git.log.execute + assert_equal(30, commits.size) end # In these tests, note that @git.log(n) is equivalent to @git.log.max_count(n) def test_log_max_count_twenty - assert_equal(20, @git.log(20).size) - assert_equal(20, @git.log.max_count(20).size) + max_count = 20 + commits = @git.log(max_count).execute + assert_equal(20, commits.size) + commits = @git.log.max_count(max_count).execute + assert_equal(20, commits.size) end def test_log_max_count_nil - assert_equal(72, @git.log(nil).size) - assert_equal(72, @git.log.max_count(nil).size) + # nil should return all commits + max_count = nil + commits = @git.log(max_count).execute + assert_equal(72, commits.size) + commits = @git.log.max_count(max_count).execute + assert_equal(72, commits.size) end def test_log_max_count_all - assert_equal(72, @git.log(:all).size) - assert_equal(72, @git.log.max_count(:all).size) + max_count = :all + commits = @git.log(max_count).execute + assert_equal(72, commits.size) + commits = @git.log.max_count(max_count).execute + assert_equal(72, commits.size) end # Note that @git.log.all does not control the number of commits returned. For that, # use @git.log.max_count(n) def test_log_all - assert_equal(72, @git.log(100).size) - assert_equal(76, @git.log(100).all.size) + commits = @git.log(100).execute + assert_equal(72, commits.size) + commits = @git.log(100).all.execute + assert_equal(76, commits.size) end def test_log_non_integer_count - assert_raises(ArgumentError) { @git.log('foo').size } + assert_raises(ArgumentError) do + commits = @git.log('foo').execute + commits.size + end end def test_get_first_and_last_entries log = @git.log - assert(log.first.is_a?(Git::Object::Commit)) - assert_equal('46abbf07e3c564c723c7c039a43ab3a39e5d02dd', log.first.objectish) + commits = log.execute + assert(commits.first.is_a?(Git::Object::Commit)) + assert_equal('46abbf07e3c564c723c7c039a43ab3a39e5d02dd', commits.first.objectish) - assert(log.last.is_a?(Git::Object::Commit)) - assert_equal('b03003311ad3fa368b475df58390353868e13c91', log.last.objectish) + assert(commits.last.is_a?(Git::Object::Commit)) + assert_equal('b03003311ad3fa368b475df58390353868e13c91', commits.last.objectish) end def test_get_log_entries - assert_equal(30, @git.log.size) - assert_equal(50, @git.log(50).size) - assert_equal(10, @git.log(10).size) + assert_equal(30, @git.log.execute.size) + assert_equal(50, @git.log(50).execute.size) + assert_equal(10, @git.log(10).execute.size) end def test_get_log_to_s - assert_equal(@git.log.to_s.split("\n").first, @git.log.first.sha) + commits = @git.log.execute + first_line = commits.to_s.split("\n").first + first_sha = commits.first.sha + assert_equal(first_line, first_sha) end def test_log_skip - three1 = @git.log(3).to_a[-1] - three2 = @git.log(2).skip(1).to_a[-1] - three3 = @git.log(1).skip(2).to_a[-1] + three1 = @git.log(3).execute.to_a[-1] + three2 = @git.log(2).skip(1).execute.to_a[-1] + three3 = @git.log(1).skip(2).execute.to_a[-1] assert_equal(three2.sha, three3.sha) assert_equal(three1.sha, three2.sha) end def test_get_log_since - l = @git.log.since('2 seconds ago') - assert_equal(0, l.size) + commits = @git.log.since('2 seconds ago').execute + assert_equal(0, commits.size) - l = @git.log.since("#{Date.today.year - 2006} years ago") - assert_equal(30, l.size) + commits = @git.log.since("#{Date.today.year - 2006} years ago").execute + assert_equal(30, commits.size) end def test_get_log_grep - l = @git.log.grep('search') - assert_equal(2, l.size) + commits = @git.log.grep('search').execute + assert_equal(2, commits.size) end def test_get_log_author - l = @git.log(5).author('chacon') - assert_equal(5, l.size) - l = @git.log(5).author('lazySusan') - assert_equal(0, l.size) + commits = @git.log(5).author('chacon').execute + assert_equal(5, commits.size) + commits = @git.log(5).author('lazySusan').execute + assert_equal(0, commits.size) end def test_get_log_since_file - l = @git.log.path('example.txt') - assert_equal(30, l.size) + commits = @git.log.path('example.txt').execute + assert_equal(30, commits.size) - l = @git.log.between('v2.5', 'test').path('example.txt') - assert_equal(1, l.size) + commits = @git.log.between('v2.5', 'test').path('example.txt').execute + assert_equal(1, commits.size) end def test_get_log_path - log = @git.log.path('example.txt') - assert_equal(30, log.size) - log = @git.log.path('example*') - assert_equal(30, log.size) - log = @git.log.path(['example.txt', 'scott/text.txt']) - assert_equal(30, log.size) + commits = @git.log.path('example.txt').execute + assert_equal(30, commits.size) + commits = @git.log.path('example*').execute + assert_equal(30, commits.size) + commits = @git.log.path(['example.txt', 'scott/text.txt']).execute + assert_equal(30, commits.size) end def test_log_file_noexist assert_raise Git::FailedError do - @git.log.object('no-exist.txt').size + @git.log.object('no-exist.txt').execute end end @@ -117,20 +138,22 @@ def test_log_with_empty_commit_message expected_message = 'message' git.commit(expected_message, { allow_empty: true }) git.commit('', { allow_empty: true, allow_empty_message: true }) - log = git.log - assert_equal(2, log.to_a.size) - assert_equal('', log[0].message) - assert_equal(expected_message, log[1].message) + commits = git.log.execute + assert_equal(2, commits.size) + assert_equal('', commits[0].message) + assert_equal(expected_message, commits[1].message) end end def test_log_cherry - l = @git.log.between('master', 'cherry').cherry - assert_equal(1, l.size) + commits = @git.log.between('master', 'cherry').cherry.execute + assert_equal(1, commits.size) end def test_log_merges expected_command_line = ['log', '--no-color', '--max-count=30', '--pretty=raw', '--merges', { chdir: nil }] - assert_command_line_eq(expected_command_line) { |git| git.log.merges.size } + assert_command_line_eq(expected_command_line) do |git| + git.log.merges.execute + end end end diff --git a/tests/units/test_merge.rb b/tests/units/test_merge.rb index cd1e7554..30991d37 100644 --- a/tests/units/test_merge.rb +++ b/tests/units/test_merge.rb @@ -94,7 +94,8 @@ def test_no_ff_merge g.branch('new_branch2').checkout g.merge('new_branch', 'merge commit message') # ff merge assert(g.status['new_file_1']) # file has been merged in - assert_equal('first commit message', g.log.first.message) # merge commit message was ignored + commits = g.log.execute + assert_equal('first commit message', commits.first.message) # merge commit message was ignored g.branch('new_branch').in_branch('second commit message') do new_file('new_file_2', 'hello') @@ -105,7 +106,8 @@ def test_no_ff_merge assert_equal('new_branch2', g.current_branch) # still in new_branch2 branch g.merge('new_branch', 'merge commit message', no_ff: true) # no-ff merge assert(g.status['new_file_2']) # file has been merged in - assert_equal('merge commit message', g.log.first.message) + commits = g.log.execute + assert_equal('merge commit message', commits.first.message) end end diff --git a/tests/units/test_pull.rb b/tests/units/test_pull.rb index 49770a7c..cdb6b768 100644 --- a/tests/units/test_pull.rb +++ b/tests/units/test_pull.rb @@ -44,9 +44,11 @@ class TestPull < Test::Unit::TestCase Dir.chdir('local') do git = Git.open('.') - assert_equal(1, git.log.size) + commits = git.log.execute + assert_equal(1, commits.size) assert_nothing_raised { git.pull } - assert_equal(2, git.log.size) + commits = git.log.execute + assert_equal(2, commits.size) end end end @@ -72,9 +74,11 @@ class TestPull < Test::Unit::TestCase Dir.chdir('local') do git = Git.open('.') - assert_equal(1, git.log.size) + commits = git.log.execute + assert_equal(1, commits.size) assert_nothing_raised { git.pull('origin') } - assert_equal(2, git.log.size) + commits = git.log.execute + assert_equal(2, commits.size) end end end @@ -104,9 +108,11 @@ class TestPull < Test::Unit::TestCase Dir.chdir('local') do git = Git.open('.') - assert_equal(1, git.log.size) + commits = git.log.execute + assert_equal(1, commits.size) assert_nothing_raised { git.pull('origin', 'feature1') } - assert_equal(3, git.log.size) + commits = git.log.execute + assert_equal(3, commits.size) end end end diff --git a/tests/units/test_remotes.rb b/tests/units/test_remotes.rb index cddc56cd..ed54536a 100644 --- a/tests/units/test_remotes.rb +++ b/tests/units/test_remotes.rb @@ -177,12 +177,14 @@ def test_fetch_ref_adds_ref_option new_file('test-file1', 'gonnaCommitYou') rem.add rem.commit('master commit 1') - first_commit_sha = rem.log.first.sha + commits = rem.log.execute + first_commit_sha = commits.first.sha new_file('test-file2', 'gonnaCommitYouToo') rem.add rem.commit('master commit 2') - second_commit_sha = rem.log.first.sha + commits = rem.log.execute + second_commit_sha = commits.first.sha end loc.chdir do diff --git a/tests/units/test_windows_cmd_escaping.rb b/tests/units/test_windows_cmd_escaping.rb index 85def7e3..dfb610bc 100644 --- a/tests/units/test_windows_cmd_escaping.rb +++ b/tests/units/test_windows_cmd_escaping.rb @@ -13,7 +13,7 @@ def test_commit_with_double_quote_in_commit_message git = Git.init('.') git.add git.commit(expected_commit_message) - commits = git.log(1) + commits = git.log(1).execute actual_commit_message = commits.first.message assert_equal(expected_commit_message, actual_commit_message) end