Skip to content

Commit 06719ea

Browse files
committed
[CodeExtractor] Fix "transferred from" in reinsert
This could be a "[FIXUP]" commit, but I think it is worth pointing out what I did here. Since there is multiple `git-filter-branch` calls, the original commit SHAs that existed are re-written after each. So delaying writing the updated commit message will only produce references to commits that don't exist since they were temporary. So moving `--msg-filter` to the first `git-filter-branch` was the first logical step. However, this caused another issue. Since we allow a fallback for finding the commit messages that existed in the previous repository, that would now be incorrect (in it's previous form) since it relied on matching the exact messages created. To handle this in most cases, and lines of `(transferred from ...@` are filtered out from the commit messages before comparing. * * * The remaining changes are just to support this change. - Adjust some method signatures to support this change. - Update `assert_commits` to confirm the commit messages are pointing to a proper commit - Add a `reference_repo_dir` and `reference_repo` to help with the `assert_commits` changes (set in one of the helper methods)
1 parent af8f2f5 commit 06719ea

File tree

3 files changed

+38
-18
lines changed

3 files changed

+38
-18
lines changed

lib/code_extractor.rb

+11-12
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,16 @@ def extract_commits extractions, upstream_name
104104
# Note: We don't use `--subdirectory-filter` here as it will remove merge
105105
# commits, which we don't want.
106106
#
107-
def prune_commits extractions
107+
def prune_commits extractions, upstream_name
108108
puts "Pruning commits…"
109109

110+
@upstream_name ||= upstream_name
111+
110112
build_prune_script extractions
111113

112114
Dir.chdir git_dir do
113115
`git checkout -b #{prune_branch} #{@source_branch}`
114-
`git filter-branch -f --prune-empty --tree-filter #{@prune_script} HEAD`
116+
`git filter-branch -f --prune-empty --tree-filter #{@prune_script} #{msg_filter upstream_name} HEAD`
115117
`git filter-branch -f --prune-empty --index-filter '
116118
git read-tree --empty
117119
git reset $GIT_COMMIT -- #{@keep_directory}
@@ -156,12 +158,10 @@ def add_target_remote target_name, target_remote
156158
# branch, and the "root" commit assumes the parent of the current HEAD of
157159
# the target remote's (master) branch
158160
#
159-
def inject_commits target_base_branch, upstream_name
161+
def inject_commits target_base_branch
160162
puts "Injecting commits…"
161163

162-
@upstream_name ||= upstream_name
163-
target_base_branch ||= 'master'
164-
164+
target_base_branch ||= 'master'
165165
@reference_target_branch = "#{target_remote_name}/#{target_base_branch}"
166166

167167
Dir.chdir git_dir do
@@ -211,9 +211,6 @@ def inject_commits target_base_branch, upstream_name
211211
else
212212
cat -
213213
fi
214-
echo
215-
echo
216-
echo "(transferred from #{upstream_name}@$GIT_COMMIT)"
217214
' -- #{inject_branch}`
218215

219216
# Old (bad: doesn't handle merges)
@@ -383,13 +380,15 @@ def previously_extracted_commits
383380
false
384381
else
385382
upstream_full_msg = `git show -s --format="%s%n%n%b" #{commit}`
383+
upstream_full_msg.gsub! /^\(transferred from #{upstream_name}@.*$/, ''
386384

387385
# TODO: Change this to a `.one?` check, and if this fails, and
388386
# there is more than one, then compare changed file base names...
389387
# which is harder still...
390388
target_commits.any? do |target_commit|
391389
target_full_msg = `git show -s --format="%s%n%n%b" #{target_commit}`
392-
upstream_full_msg == target_full_msg
390+
target_full_msg.gsub! /^\(transferred from #{upstream_name}@.*$/, ''
391+
upstream_full_msg.strip == target_full_msg.strip
393392
end
394393
end
395394
end
@@ -443,10 +442,10 @@ def extract
443442
def reinsert
444443
return unless @config[:reinsert]
445444

446-
@source_project.prune_commits @config[:extractions]
445+
@source_project.prune_commits @config[:extractions], @config[:upstream_name]
447446
@source_project.run_extra_cmds @config[:extra_cmds]
448447
@source_project.add_target_remote @config[:target_name], @config[:target_remote]
449-
@source_project.inject_commits @config[:target_base_branch], @config[:upstream_name]
448+
@source_project.inject_commits @config[:target_base_branch]
450449

451450
true
452451
end

test/code_extractor_reinsert_test.rb

+1
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ def apply_new_commits_on_extracted_repo &block
240240
end
241241
end
242242

243+
self.reference_repo_dir = @cloned_extractions_dir
243244
CodeExtractor::TestRepo.clone_at(extracted_dir, @cloned_extractions_dir, &block)
244245
end
245246

test/test_helper.rb

+26-6
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ module CodeExtractor
2121
# test, and clean up when it is done.
2222
#
2323
class TestCase < Minitest::Test
24-
attr_writer :extractions, :extractions_hash
24+
attr_writer :extractions, :extractions_hash, :reference_repo_dir
2525
attr_reader :extracted_dir, :repo_dir, :sandbox_dir
2626

2727
# Create a sandbox for the given test, and name it after the test class and
@@ -61,14 +61,30 @@ def assert_no_tags
6161
assert tags.empty?, "Expected there to be no tags, but got `#{tags.join ', '}'"
6262
end
6363

64+
TRANSFERRED_FROM_REGEXP = /\(transferred from (?<UPSTREAM>[^@]*)@(?<SHA>[^\)]*)\)/
6465
def assert_commits expected_commits
6566
start_commit = destination_repo.last_commit
6667
sorting = Rugged::SORT_TOPO # aka: sort like git-log
67-
actual_commits = destination_repo.walk(start_commit, sorting).map(&:message)
68-
69-
actual_commits.map! { |msg| msg.lines.first.chomp }
70-
71-
assert_equal expected_commits, actual_commits
68+
actual_commits = destination_repo.walk(start_commit, sorting).map {|c| c }
69+
commit_msgs = actual_commits.map { |commit| commit.message.lines.first.chomp }
70+
71+
assert_equal expected_commits, commit_msgs
72+
73+
# Check that the "transferred from ..." reference line is correct
74+
actual_commits.map do |commit|
75+
[
76+
commit,
77+
commit.message.lines.last.match(TRANSFERRED_FROM_REGEXP)
78+
]
79+
end.each do |commit, transfered|
80+
next unless transfered
81+
82+
transferred_commit = reference_repo.lookup(transfered[:SHA])
83+
assert transferred_commit.is_a?(Rugged::Commit),
84+
"'transfered from' of #{transfered[:SHA]} from #{commit} is not a valid commit"
85+
assert_equal commit.message.lines.first.chomp,
86+
transferred_commit.message.lines.first.chomp
87+
end
7288
end
7389

7490
# Helper methods
@@ -81,6 +97,10 @@ def destination_repo
8197
@destination_repo ||= Rugged::Repository.new @extracted_dir
8298
end
8399

100+
def reference_repo
101+
@reference_repo ||= Rugged::Repository.new @reference_repo_dir
102+
end
103+
84104
def current_commit_message
85105
destination_repo.head.target.message
86106
end

0 commit comments

Comments
 (0)