filter-repo: allow rewriting of hashes in commit messages to be toggled

Signed-off-by: Elijah Newren <newren@gmail.com>
This commit is contained in:
Elijah Newren 2019-05-11 18:45:49 -07:00
parent 49ff9a74e8
commit 76b71fe92d
2 changed files with 42 additions and 7 deletions

View File

@ -834,6 +834,7 @@ class FastExportFilter(object):
def __init__(self, repo_working_dir,
empty_pruning = 'auto',
degenerate_pruning = 'auto',
preserve_commit_hashes = False,
tag_callback = None, commit_callback = None,
blob_callback = None, progress_callback = None,
reset_callback = None, checkpoint_callback = None,
@ -841,6 +842,13 @@ class FastExportFilter(object):
# Repo we are exporting
self._repo_working_dir = repo_working_dir
# Record other preferences about operation from passed-in args
assert(empty_pruning in ['always', 'auto', 'never'])
self._empty_pruning = empty_pruning
assert(degenerate_pruning in ['always', 'auto', 'never'])
self._degenerate_pruning = degenerate_pruning
self._preserve_commit_hashes = preserve_commit_hashes
# Members below simply store callback functions for the various git
# elements
self._tag_callback = tag_callback
@ -930,12 +938,6 @@ class FastExportFilter(object):
# to subsequent commits being empty
self._files_tweaked = set()
# Whether to do empty or degenerate pruning
assert(empty_pruning in ['always', 'auto', 'never'])
self._empty_pruning = empty_pruning
assert(degenerate_pruning in ['always', 'auto', 'never'])
self._degenerate_pruning = degenerate_pruning
# Compile some regexes and cache those
self._mark_re = re.compile(br'mark :(\d+)\n$')
self._parent_regexes = {}
@ -1451,7 +1453,8 @@ class FastExportFilter(object):
(committer_name, committer_email, committer_date)
commit_msg = self._parse_data()
commit_msg = self._hash_re.sub(self._translate_commit_hash, commit_msg)
if not self._preserve_commit_hashes:
commit_msg = self._hash_re.sub(self._translate_commit_hash, commit_msg)
pinfo = [self._parse_optional_parent_ref(b'from')]
# Due to empty pruning, we can have real 'from' and 'merge' lines that
@ -2011,6 +2014,15 @@ class FilteringOptions(object):
"example, --tag-rename foo:bar will rename tag foo-1.2.3 "
"to bar-1.2.3; either OLD or NEW can be empty."))
messages = parser.add_argument_group(title=_("Filtering of commit messages "
"(see also --message-callback)"))
messages.add_argument('--preserve-commit-hashes', action='store_true',
help=_("By default, since commits are rewritten and thus gain new "
"hashes, references to old commit hashes in commit messages "
"are replaced with new commit hashes (abbreviated to the same "
"length as the old reference). Use this flag to turn off "
"updating commit hashes in commit messages."))
people = parser.add_argument_group(title=_("Filtering of names & emails "
"(see also --name-callback "
"and --email-callback)"))
@ -3244,6 +3256,7 @@ class RepoFilter(object):
fef = FastExportFilter(self._args.source or '.',
empty_pruning = self._args.empty_pruning,
degenerate_pruning = self._args.degenerate_pruning,
preserve_commit_hashes = self._args.preserve_commit_hashes,
blob_callback = actual_blob_callback,
commit_callback = actual_commit_callback,
tag_callback = actual_tag_callback,

View File

@ -650,17 +650,39 @@ test_expect_success 'commit message rewrite' '
git log --oneline >changes &&
test_line_count = 204 changes &&
# If a commit we reference is rewritten, we expect the
# reference to be rewritten.
name=$(git rev-parse HEAD~203) &&
echo "Commit referencing ${name:0:8}" >expect &&
git log --no-walk --format=%s HEAD~202 >actual &&
test_cmp expect actual &&
# If a commit we reference was pruned, then the reference
# has nothing to be rewritten to. Verify that the commit
# ID it points to does not exist.
latest=$(git log --no-walk | grep reverts | awk "{print \$4}" | tr -d '.') &&
test -n "$latest" &&
test_must_fail git cat-file -e "$latest"
)
'
test_expect_success 'commit hash unchanged if requested' '
(
git clone file://"$(pwd)"/commit_msg commit_msg_clone_2 &&
cd commit_msg_clone_2 &&
name=$(git rev-parse HEAD~204) &&
git filter-repo --invert-paths --path bar --preserve-commit-hashes &&
git log --oneline >changes &&
test_line_count = 204 changes &&
echo "Commit referencing ${name:0:8}" >expect &&
git log --no-walk --format=%s HEAD~202 >actual &&
test_cmp expect actual
)
'
test_expect_success 'commit message rewrite unsuccessful' '
(
git init commit_msg_not_found &&