Skip to content

Commit

Permalink
filter-branch: eliminate duplicate mapped parents
Browse files Browse the repository at this point in the history
When multiple parents of a merge commit get mapped to the same
commit, filter-branch used to pass all instances of the parent
commit to the parent and commit filters and to "git commit-tree" or
"git_commit_non_empty_tree".

This can often happen when extracting a small project from a large
repository; merges can join history with no commits on any branch
which affect the paths being retained.  Once the intermediate
commits have been filtered out, all the immediate parents of the
merge commit can end up being mapped to the same commit - either the
original merge-base or an ancestor of it.

"git commit-tree" would display an error but write the commit with
the normalized parents in any case.  "git_commit_non_empty_tree"
would fail to notice that the commit being made was in fact a
non-merge commit and would retain it even if a further pass with
"--prune-empty" would discard the commit as empty.

Ensure that duplicate parents are pruned before the parent filter to
make "--prune-empty" idempotent, removing all empty non-merge
commits in a singe pass.

Signed-off-by: Charles Bailey <cbailey32@bloomberg.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Charles Bailey authored and Junio C Hamano committed Jul 1, 2014
1 parent 341e7e8 commit 79bc4ef
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
8 changes: 7 additions & 1 deletion git-filter-branch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,13 @@ while read commit parents; do
parentstr=
for parent in $parents; do
for reparent in $(map "$parent"); do
parentstr="$parentstr -p $reparent"
case "$parentstr " in
*" -p $reparent "*)
;;
*)
parentstr="$parentstr -p $reparent"
;;
esac
done
done
if [ "$filter_parent" ]; then
Expand Down
11 changes: 11 additions & 0 deletions t/t7003-filter-branch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,17 @@ test_expect_success 'Prune empty commits' '
test_cmp expect actual
'

test_expect_success 'prune empty collapsed merges' '
test_config merge.ff false &&
git rev-list HEAD >expect &&
test_commit to_remove_2 &&
git reset --hard HEAD^ &&
test_merge non-ff to_remove_2 &&
git filter-branch -f --index-filter "git update-index --remove to_remove_2.t" --prune-empty HEAD &&
git rev-list HEAD >actual &&
test_cmp expect actual
'

test_expect_success '--remap-to-ancestor with filename filters' '
git checkout master &&
git reset --hard A &&
Expand Down

0 comments on commit 79bc4ef

Please sign in to comment.