Skip to content

Commit a7f9ac4

Browse files
authored
Avoid extra commit id changes by respecting Git tree ordering
A no-op test rewrite of git-filter-repo, using `git-filter-repo --proceed`, unexpectedly results in a different tree. Diffing the fast-export dumps with `--dry-run`, it appears git-filter-repo is using Python's default sorting algorithm for Git trees, rather than the Git-specific algorithm, which is described a bit at: https://stackoverflow.com/questions/78981525/how-git-sort-entries-in-trees ``` @@ -1451,25 +1329,23 @@ D testcases/expected/case1-twenty D testcases/inputs/case1 M 100755 0a13abf testcases/t9390-repo-filter.sh +M 100644 de3799f testcases/t9390/case1 M 100644 e0c8845 testcases/t9390/case1-filename M 100644 a1aa78f testcases/t9390/case1-ten M 100644 488cbd9 testcases/t9390/case1-twenty -M 100644 de3799f testcases/t9390/case1 ``` Unlike described above though, it appears the fast-export dumps treats all files as directory when sorting them (`case1` is a file in the example above), so appending "/" to all entries maintains the original tree order. This avoids unnecessary tree hash variation and early, cascading commit id changes, which shouldn't happen before a commit is effectively rewritten by git-filter-repo. With this change, `git-filter-repo --proceed` is stable and produces an identical repository.
1 parent 2d39146 commit a7f9ac4

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

git-filter-repo

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3940,7 +3940,9 @@ class RepoFilter(object):
39403940
continue
39413941
# Otherwise, record the change
39423942
new_file_changes[change.filename] = change
3943-
commit.file_changes = [v for k,v in sorted(new_file_changes.items())]
3943+
# Use the Git sorting algorithm for trees
3944+
commit.file_changes = [v for k,v in sorted(new_file_changes.items(),
3945+
key=lambda x: (x[0]+b'/', x[1]))]
39443946

39453947
def _tweak_commit(self, commit, aux_info):
39463948
if self._args.replace_message:

0 commit comments

Comments
 (0)