'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 can be pushed to
its ancestor in this case.

Signed-off-by: Dave Ware <dav...@realtimegenomics.com>
---

Notes:
    Many thanks to Eric Sunshine and Junio Hamano for adivce on this patch
    
    Changes since v3:
    - Improvements to commit message
    - Removed incorrect use of --boundary on rev-list
    - Changed use of rev-list to use --count
    Changes since v2:
    - Minor improvements to commit message
    - Changed space indentation to tab indentation in test case
    - Changed use of rev-list for obtaining commit id to use rev-parse instead
    Changes since v1:
    - Minor improvements to commit message
    - Added sign off
    - Moved test case from own file into t7900-subtree.sh
    - Added subshell to test around 'cd'
    - Moved record of commit for cherry-pick to variable instead of dumping 
into file
    
    [v3]: 
http://thread.gmane.org/gmane.comp.version-control.git/282065/focus=282176
    [v2]: 
http://thread.gmane.org/gmane.comp.version-control.git/282065/focus=282121
    [v1]: http://thread.gmane.org/gmane.comp.version-control.git/282065

 contrib/subtree/git-subtree.sh     | 12 +++++++--
 contrib/subtree/t/t7900-subtree.sh | 52 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 9f06571..ebf99d9 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -479,8 +479,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 9051982..710278c 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -468,4 +468,56 @@ test_expect_success 'verify one file change per commit' '
        ))
 '
 
+test_expect_success 'subtree descendent check' '
+       mkdir git_subtree_split_check &&
+       (
+               cd git_subtree_split_check &&
+               git init &&
+
+               mkdir folder &&
+
+               echo a >folder/a &&
+               git add . &&
+               git commit -m "first commit" &&
+
+               git branch branch &&
+
+               echo 0 >folder/0 &&
+               git add . &&
+               git commit -m "adding 0 to folder" &&
+
+               echo b >folder/b &&
+               git add . &&
+               git commit -m "adding b to folder" &&
+               cherry=$(git rev-parse HEAD) &&
+
+               git checkout branch &&
+               echo text >textBranch.txt &&
+               git add . &&
+               git commit -m "commit to fiddle with branch: branch" &&
+
+               git cherry-pick $cherry &&
+               git checkout master &&
+               git merge -m "merge" branch &&
+
+               git branch noop_branch &&
+
+               echo d >folder/d &&
+               git add . &&
+               git commit -m "adding d to folder" &&
+
+               git checkout noop_branch &&
+               echo moreText >anotherText.txt &&
+               git add . &&
+               git commit -m "irrelevant" &&
+
+               git checkout master &&
+               git merge -m "second merge" noop_branch &&
+
+               git subtree split --prefix folder/ --branch subtree_tip master 
&&
+               git subtree split --prefix folder/ --branch subtree_branch 
branch &&
+               git push . subtree_tip:subtree_branch
+       )
+       '
+
 test_done
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to