filter-repo: use more expensive prunability checks when needed

When users are inserting new objects into the stream, we cannot make as
many assumptions and need to do more careful checks for whether commits
become empty or not.

Signed-off-by: Elijah Newren <newren@gmail.com>
pull/71/head
Elijah Newren 4 years ago
parent b1fae4819a
commit 4f84a74ada

@ -372,6 +372,12 @@ class _IDs(object):
# A map of new-ids to every old-id that points to the new-id (1:N map)
self._reverse_translation = {}
def has_renames(self):
"""
Return whether there have been ids remapped to new values
"""
return bool(self._translation)
def new(self):
"""
Should be called whenever a new blob or commit object is created. The
@ -3121,12 +3127,16 @@ class RepoFilter(object):
if not self._import_pipes:
return False
# non-merge commits can only be empty if blob/file-change editing caused
# all file changes in the commit to have the same file contents as
# the parent.
changed_files = set(change.filename for change in commit.file_changes)
if len(orig_parents) < 2 and changed_files - self._files_tweaked:
return False
# If there have not been renames/remappings of IDs (due to insertion of
# new blobs), then we can sometimes know things aren't prunable with a
# simple check
if not _IDS.has_renames():
# non-merge commits can only be empty if blob/file-change editing caused
# all file changes in the commit to have the same file contents as
# the parent.
changed_files = set(change.filename for change in commit.file_changes)
if len(orig_parents) < 2 and changed_files - self._files_tweaked:
return False
# Finally, the hard case: due to either blob rewriting, or due to pruning
# of empty commits wiping out the first parent history back to the merge

@ -7,6 +7,7 @@ test_description='Usage of git-filter-repo as a library'
export PYTHONPATH=$(dirname $TEST_DIRECTORY):$PYTHONPATH
# Avoid writing git_filter_repo.pyc file
export PYTHONDONTWRITEBYTECODE=1
export CONTRIB_DIR=$TEST_DIRECTORY/../contrib/filter-repo-demos
setup()
{
@ -163,4 +164,27 @@ test_expect_success 'other error cases' '
)
'
test_expect_success 'lint-history' '
test_create_repo lint-history &&
(
cd lint-history &&
echo initial >content &&
git add content &&
git commit -m "initial" &&
printf "CRLF is stupid\r\n" >content &&
git add content &&
git commit -m "make a statement" &&
printf "CRLF is stupid\n" >content &&
git add content &&
git commit -m "oops, that was embarassing" &&
$CONTRIB_DIR/lint-history --filenames-important dos2unix &&
echo 2 >expect &&
git rev-list --count HEAD >actual &&
test_cmp expect actual
)
'
test_done

Loading…
Cancel
Save