contrib/subtree: fix "subtree split" skipped-merge bug
'git subtree split' can incorrectly skip a merge even when both parents act on the subtree, provided the merge results in a tree identical to one of the parents. Fix by copying the merge if at least one parent is non-identical, and the non-identical parent is not an ancestor of the identical parent. Also, add a test case which checks that a descendant remains a descendent on the subtree in this case. Signed-off-by: Dave Ware <davidw@realtimegenomics.com> Reviewed-by: David A. Greene <greened@obbligato.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
30fe9b2f9a
commit
933cfeb90b
@ -480,7 +480,15 @@ copy_or_skip()
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ -n "$identical" ]; then
|
copycommit=
|
||||||
|
if [ -n "$identical" ] && [ -n "$nonidentical" ]; then
|
||||||
|
extras=$(git rev-list --count $identical..$nonidentical)
|
||||||
|
if [ "$extras" -ne 0 ]; then
|
||||||
|
# we need to preserve history along the other branch
|
||||||
|
copycommit=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ -n "$identical" ] && [ -z "$copycommit" ]; then
|
||||||
echo $identical
|
echo $identical
|
||||||
else
|
else
|
||||||
copy_commit $rev $tree "$p" || exit $?
|
copy_commit $rev $tree "$p" || exit $?
|
||||||
|
@ -1014,4 +1014,64 @@ test_expect_success 'push split to subproj' '
|
|||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
#
|
||||||
|
# This test covers 2 cases in subtree split copy_or_skip code
|
||||||
|
# 1) Merges where one parent is a superset of the changes of the other
|
||||||
|
# parent regarding changes to the subtree, in this case the merge
|
||||||
|
# commit should be copied
|
||||||
|
# 2) Merges where only one parent operate on the subtree, and the merge
|
||||||
|
# commit should be skipped
|
||||||
|
#
|
||||||
|
# (1) is checked by ensuring subtree_tip is a descendent of subtree_branch
|
||||||
|
# (2) should have a check added (not_a_subtree_change shouldn't be present
|
||||||
|
# on the produced subtree)
|
||||||
|
#
|
||||||
|
# Other related cases which are not tested (or currently handled correctly)
|
||||||
|
# - Case (1) where there are more than 2 parents, it will sometimes correctly copy
|
||||||
|
# the merge, and sometimes not
|
||||||
|
# - Merge commit where both parents have same tree as the merge, currently
|
||||||
|
# will always be skipped, even if they reached that state via different
|
||||||
|
# set of commits.
|
||||||
|
#
|
||||||
|
|
||||||
|
next_test
|
||||||
|
test_expect_success 'subtree descendant check' '
|
||||||
|
subtree_test_create_repo "$subtree_test_count" &&
|
||||||
|
test_create_commit "$subtree_test_count" folder_subtree/a &&
|
||||||
|
(
|
||||||
|
cd "$subtree_test_count" &&
|
||||||
|
git branch branch
|
||||||
|
) &&
|
||||||
|
test_create_commit "$subtree_test_count" folder_subtree/0 &&
|
||||||
|
test_create_commit "$subtree_test_count" folder_subtree/b &&
|
||||||
|
cherry=$(cd "$subtree_test_count"; git rev-parse HEAD) &&
|
||||||
|
(
|
||||||
|
cd "$subtree_test_count" &&
|
||||||
|
git checkout branch
|
||||||
|
) &&
|
||||||
|
test_create_commit "$subtree_test_count" commit_on_branch &&
|
||||||
|
(
|
||||||
|
cd "$subtree_test_count" &&
|
||||||
|
git cherry-pick $cherry &&
|
||||||
|
git checkout master &&
|
||||||
|
git merge -m "merge should be kept on subtree" branch &&
|
||||||
|
git branch no_subtree_work_branch
|
||||||
|
) &&
|
||||||
|
test_create_commit "$subtree_test_count" folder_subtree/d &&
|
||||||
|
(
|
||||||
|
cd "$subtree_test_count" &&
|
||||||
|
git checkout no_subtree_work_branch
|
||||||
|
) &&
|
||||||
|
test_create_commit "$subtree_test_count" not_a_subtree_change &&
|
||||||
|
(
|
||||||
|
cd "$subtree_test_count" &&
|
||||||
|
git checkout master &&
|
||||||
|
git merge -m "merge should be skipped on subtree" no_subtree_work_branch &&
|
||||||
|
|
||||||
|
git subtree split --prefix folder_subtree/ --branch subtree_tip master &&
|
||||||
|
git subtree split --prefix folder_subtree/ --branch subtree_branch branch &&
|
||||||
|
check_equal $(git rev-list --count subtree_tip..subtree_branch) 0
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user