summaryrefslogtreecommitdiff
path: root/contrib/subtree
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2016-02-03 14:16:03 -0800
committerLibravatar Junio C Hamano <gitster@pobox.com>2016-02-03 14:16:03 -0800
commitdd65a9e5e3b6298e4fa52e21680008e7fd5556ea (patch)
treead06b92e0951d01a9bb5dc7085638d80420f29a0 /contrib/subtree
parentMerge branch 'tb/complete-word-diff-regex' (diff)
parentcontrib/subtree: fix "subtree split" skipped-merge bug (diff)
downloadtgif-dd65a9e5e3b6298e4fa52e21680008e7fd5556ea.tar.xz
Merge branch 'dw/subtree-split-do-not-drop-merge'
The "split" subcommand of "git subtree" (in contrib/) incorrectly skipped merges when it shouldn't, which was corrected. * dw/subtree-split-do-not-drop-merge: contrib/subtree: fix "subtree split" skipped-merge bug
Diffstat (limited to 'contrib/subtree')
-rwxr-xr-xcontrib/subtree/git-subtree.sh12
-rwxr-xr-xcontrib/subtree/t/t7900-subtree.sh60
2 files changed, 70 insertions, 2 deletions
diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index efbdb720e6..7a39b30ad0 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -485,8 +485,16 @@ copy_or_skip()
p="$p -p $parent"
fi
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
else
copy_commit $rev $tree "$p" || exit $?
diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh
index 751aee3a0c..3bf96a9bb6 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -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