Restore prefer-rebase to its previous behavior--still working on tests.
authorStephen Haberman <stephen@exigencecorp.com>
Mon, 29 Sep 2008 07:44:40 +0000 (02:44 -0500)
committerStephen Haberman <stephen@exigencecorp.com>
Mon, 29 Sep 2008 07:44:40 +0000 (02:44 -0500)
server/update-prefer-rebase
tests/t2300-server-update-prefer-rebase.sh
tests/t2301-server-update-prefer-rebase-even-if-merges.sh
tests/t2302-server-update-prefer-rebase-new-parent.sh [new file with mode: 0644]

index 8194733..fab594d 100644 (file)
@@ -5,32 +5,36 @@
 # If they are introducing non-merge commits /and/ merge commits, it could
 # look like one of two ways. This way:
 #
-# * --- B --- * --- oldrev
-#        \             \
-#        new --- new --- newrev
+# A -- B             <-- origin/topic
+#  \    \
+#   c -- d           <-- topic
 #
 # They basically had an un-shared local dev branch (probably by making a
 # merge) and instead should have done a rebase. Also, if they did:
 #
-# * --- B --- * --- oldrev
-#        \             \
-#        new --- new --- new -- newrev
+# A -- B             <-- origin/topic
+#  \    \
+#   c -- d -- e      <-- topic
 #
 # We should try and catch them--where the merge happened previously to
 # them doing more work in the newrev commit.
 #
 # But if it looks like:
 #
-# * --- B --- * --- oldrev
-#        \              \
-#        old --- new --- newrev
+# A -- B             <-- origin/foo
+#  \    \
+#   C    \           <-- origin/topic
+#    \    \
+#     d -- e         <-- topic
 #
 # Then they had a pre-shared branch that cannot be rebased and so they
 # were correct in doing a merge to tie "old" and "oldrev" together.
 #
 # Also, we obviously have to be okay with:
 #
-# * --- * --- * --- oldrev --- new --- new --- newrev
+# A -- B            <-- origin/topic
+#       \
+#        c -- d     <-- topic
 
 refname="$1"
 oldrev="$2"
@@ -56,10 +60,9 @@ git rev-parse --not --branches | git rev-list --stdin $oldrev..$newrev | while r
                git merge-base --all $parents | while read baserev ; do
                        # For each parent
                        git rev-list -n 1 --parents $commit | sed 's/ /\n/g' | grep -v $commit | while read parent ; do
-                               parent_is_old=$(git branch --contains $parent | wc -l)
                                all_commits=$(git rev-list --first-parent $baserev..$parent | wc -l)
                                new_commits=$(git rev-parse --not --branches | git rev-list --stdin $baserev..$parent | wc -l)
-                               if [ $parent_is_old -gt 0 -a $all_commits -eq $new_commits ] ; then
+                               if [ $all_commits -eq $new_commits ] ; then
                                        # echo "parent=$parent"
                                        # echo "all_commits=$all_commits"
                                        # echo "new_commits=$new_commits"
index b7bb60c..ccc8a2a 100644 (file)
@@ -18,9 +18,7 @@ test_expect_success 'setup' '
 
 install_update_hook 'update-prefer-rebase'
 
-test_expect_success 'all local changes do not need a merge' '
-       # server is on "setup"
-
+test_expect_success 'merge local changes is caught' '
        # make an outstanding change for us--but do not push
        echo "$test_name" >a.client1 &&
        git add a.client1 &&
@@ -42,9 +40,7 @@ test_expect_success 'all local changes do not need a merge' '
        git reset --hard origin/master
 '
 
-test_expect_success 'all local changes do not need a merge even with more commits after' '
-       # server is on "setup"
-
+test_expect_success 'merge local changes followed by more commits is caught' '
        # make an outstanding change for us--but do not push
        echo "$test_name" >a.client1 &&
        git add a.client1 &&
@@ -70,9 +66,7 @@ test_expect_success 'all local changes do not need a merge even with more commit
        git reset --hard origin/master
 '
 
-test_expect_success 'already shared topic changes do warrant a merge' '
-       # server is on "setup"
-
+test_expect_success 'merge shared changes from another topic is okay' '
        # make a change on topic for us and share it
        git checkout -b topic master &&
        echo "$test_name" >a.client1 &&
@@ -80,7 +74,7 @@ test_expect_success 'already shared topic changes do warrant a merge' '
        git commit -m "$test_name on client1 and topic" &&
        git push origin topic &&
 
-       # make an outstanding change that we will have to merge later
+       # make an outstanding on topic that is not pushed
        echo "$test_name again" >>a.client1 &&
        git commit -a -m "$test_name on client1 and topic again" &&
 
@@ -93,7 +87,9 @@ test_expect_success 'already shared topic changes do warrant a merge' '
        # go back to our client and it will merge in our changes
        cd .. &&
        git checkout master &&
+       # this should fast fwd
        git pull &&
+       # this pulls in the shared branch+its new tip
        git merge topic &&
 
        git push
index 470cb1c..fca8c30 100644 (file)
@@ -22,8 +22,17 @@ test_expect_success 'setup' '
        git push origin stable
 '
 
-install_server_hook 'update-prefer-rebase' 'update'
+install_update_hook 'update-prefer-rebase'
 
+#
+# A -- B         <-- origin/stable
+#  \   |
+#   C -- D       <-- origin/topic1
+#    \ |  \
+#      e - f     <-- topic1
+#
+# Nope: should rebase e ontop of D
+#
 test_expect_success 'merging in stable does not fool the script' '
        # start our branch, and share it
        git checkout -b topic1 stable &&
@@ -48,7 +57,7 @@ test_expect_success 'merging in stable does not fool the script' '
        git commit -m "topic1 changed by client2" &&
        cd .. &&
 
-       # now locally try and merge in stable (even though we are out of date)
+       # now locally try and merge in stable (even though topic1 is out of date)
        git checkout topic1 &&
        git merge stable &&
 
@@ -59,22 +68,28 @@ test_expect_success 'merging in stable does not fool the script' '
        # Make a new merge commit
        git pull &&
        ! git push 2>push.err &&
-       cat push.err | grep "It looks like you should rebase instead of merging"
+       cat push.err | grep "It looks like you should rebase instead of merging" &&
+
+       # Now fix it
+       git reset --hard ORIG_HEAD &&
+       GIT_EDITOR=: git rebase -i -p origin/topic1 &&
+       git push &&
+       git branch -r --contains stable | grep origin/topic
 '
 
 #
-# A --C------            stable
+# A --C------            <-- origin/stable
 #  \  |      \
-#   B -- D -- E -- F     topic2
+#   B -- D -- E -- F     <-- origin/topic2
 #    \|             \
-#     G -- H ------- I   attempted push
+#     g -- h ------- i   <-- topic2
 #
-# Trying to push F..I
+# Trying to push F..i
 #
-# merge-base(F, H) has two options: B and C
+# merge-base(F, h) has two options: B and C
 #
 test_expect_success 'merging in stable with tricky double baserev does not fool the script' '
-       # start our branch, and share it--commit B
+       # B: start our branch, and share it
        git checkout -b topic2 stable &&
        git config --add branch.topic2.remote origin &&
        git config --add branch.topic2.merge refs/heads/topic2 &&
@@ -83,39 +98,47 @@ test_expect_success 'merging in stable with tricky double baserev does not fool
        git commit -m "commit B created topic2" &&
        git push origin topic2 &&
 
-       # now, separately, move ahead stable, and share it--commit C
+       # C: now, separately, move ahead stable, and share it
        git checkout stable
        echo "commit C" >a &&
        git commit -a -m "commit C moved stable" &&
        git push origin stable &&
 
-       # have another client commit (in this case, it is the server, but close enough) moves topic2
+       # D: have another client commit (in this case, it is the server, but close enough) moves topic2
        cd server &&
        git checkout topic2 &&
+       # We might have cruft from the previous test
+       git reset --hard &&
        echo "commit D continuing topic2" >a.client2 &&
        git add a.client2 &&
        git commit -m "commit D by client2" &&
 
-       # Go ahead and merge in stable by the other client--commit E
+       # E: another client merges stable
        git merge stable &&
 
-       # Then move topic2 put to--commit F
+       # F: another client moves topic2 again
        echo "commit F" >a.client2 &&
        git commit -a -m "commit F by client2" &&
        cd .. &&
 
-       # now locally try and merge in stable (even though we are out of date)--commit G
+       # g: now locally try and merge in stable (even though topic2 is out of date)
        git checkout topic2 &&
        git merge stable &&
 
-       # Go ahead and move our local topic2
+       # h: advance local topic2
        echo "commit H" >a.topic2 &&
        git commit -a -m "commit H continues local fork" &&
 
-       # Make a new merge commit
+       # i: make a new merge commit
        git pull &&
-       ! git push origin topic2
+       ! git push origin topic2 2>push.err &&
        cat push.err | grep "It looks like you should rebase instead of merging"
+
+       # Now fix it
+       # git reset --hard ORIG_HEAD &&
+       # GIT_EDITOR=: git rebase -i -p origin/topic2 &&
+       # git push &&
+       # git branch -r --contains stable | grep origin/topic2
 '
 
 test_done
diff --git a/tests/t2302-server-update-prefer-rebase-new-parent.sh b/tests/t2302-server-update-prefer-rebase-new-parent.sh
new file mode 100644 (file)
index 0000000..b7f33e3
--- /dev/null
@@ -0,0 +1,113 @@
+#!/bin/sh
+
+test_description='server update prefer rebase'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+       echo "setup" >a &&
+       git add a &&
+       git commit -m "setup" &&
+       git clone ./. server &&
+       rm -fr server/.git/hooks &&
+       git remote add origin ./server &&
+       git config --add branch.master.remote origin &&
+       git config --add branch.master.merge refs/heads/master &&
+       git fetch
+'
+
+install_update_hook 'update-prefer-rebase'
+
+test_expect_success 'one new, one old parent is okay' '
+       # server is on "setup"
+
+       # make an outstanding change for us--but do not push
+       echo "$test_name" >a.client1 &&
+       git add a.client1 &&
+       git commit -m "$test_name on client1" &&
+
+       # have another client commit (in this case, it is the server, but close enough)
+       cd server &&
+       echo "$test_name" >a.client2 &&
+       git add a.client2 &&
+       git commit -m "$test_name on client2" &&
+       cd .. &&
+
+       # go back to our client and it will merge in our changes
+       git pull &&
+       merge=$(git rev-parse HEAD) &&
+
+       ! git push 2>push.err &&
+       cat push.err | grep "It looks like you should rebase instead of merging $merge" &&
+       git reset --hard origin/master
+'
+
+test_done
+
+test_expect_success 'all local changes do not need a merge even with more commits after' '
+       # server is on "setup"
+
+       # make an outstanding change for us--but do not push
+       echo "$test_name" >a.client1 &&
+       git add a.client1 &&
+       git commit -m "$test_name on client1" &&
+
+       # have another client commit (in this case, it is the server, but close enough)
+       cd server &&
+       echo "$test_name" >a.client2 &&
+       git add a.client2 &&
+       git commit -m "$test_name on client2" &&
+
+       # go back to our client and it will merge in our changes
+       cd .. &&
+       git pull &&
+       merge=$(git rev-parse HEAD) &&
+
+       # To complicate things, have them add another change
+       echo "$test_name again" >a.client1 &&
+       git commit -a -m "$test_name on client1 again" &&
+
+       ! git push 2>push.err &&
+       cat push.err | grep "It looks like you should rebase instead of merging $merge" &&
+       git reset --hard origin/master
+'
+
+test_expect_success 'already shared topic changes do warrant a merge' '
+       # server is on "setup"
+
+       # make a change on topic for us and share it
+       git checkout -b topic master &&
+       echo "$test_name" >a.client1 &&
+       git add a.client1 &&
+       git commit -m "$test_name on client1 and topic" &&
+       git push origin topic &&
+
+       # make an outstanding change that we will have to merge later
+       echo "$test_name again" >>a.client1 &&
+       git commit -a -m "$test_name on client1 and topic again" &&
+
+       # have another client commit to master (in this case, it is the server, but close enough)
+       cd server &&
+       echo "$test_name" >a.client2 &&
+       git add a.client2 &&
+       git commit -m "$test_name on client2" &&
+
+       # go back to our client and it will merge in our changes
+       cd .. &&
+       git checkout master &&
+       git pull &&
+       git merge topic &&
+
+       git push
+'
+
+test_expect_success 'simple commit' '
+       # go back to topic and make a simple commit/push as a sanity check
+       git checkout topic &&
+       echo "$test_name" >>a.client1 &&
+       git commit -a -m "$test_name on client1 and topic" &&
+       git push
+'
+
+test_done
+