From 2b6908d8d60b827d3f04a56e1ea892a05d88d1c7 Mon Sep 17 00:00:00 2001 From: Stephen Haberman Date: Mon, 29 Sep 2008 02:44:40 -0500 Subject: [PATCH] Restore prefer-rebase to its previous behavior--still working on tests. --- server/update-prefer-rebase | 27 +++-- tests/t2300-server-update-prefer-rebase.sh | 16 +-- ...ver-update-prefer-rebase-even-if-merges.sh | 57 ++++++--- ...-server-update-prefer-rebase-new-parent.sh | 113 ++++++++++++++++++ 4 files changed, 174 insertions(+), 39 deletions(-) create mode 100644 tests/t2302-server-update-prefer-rebase-new-parent.sh diff --git a/server/update-prefer-rebase b/server/update-prefer-rebase index 8194733..fab594d 100644 --- a/server/update-prefer-rebase +++ b/server/update-prefer-rebase @@ -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" diff --git a/tests/t2300-server-update-prefer-rebase.sh b/tests/t2300-server-update-prefer-rebase.sh index b7bb60c..ccc8a2a 100644 --- a/tests/t2300-server-update-prefer-rebase.sh +++ b/tests/t2300-server-update-prefer-rebase.sh @@ -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 diff --git a/tests/t2301-server-update-prefer-rebase-even-if-merges.sh b/tests/t2301-server-update-prefer-rebase-even-if-merges.sh index 470cb1c..fca8c30 100644 --- a/tests/t2301-server-update-prefer-rebase-even-if-merges.sh +++ b/tests/t2301-server-update-prefer-rebase-even-if-merges.sh @@ -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 index 0000000..b7f33e3 --- /dev/null +++ b/tests/t2302-server-update-prefer-rebase-new-parent.sh @@ -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 + -- 2.39.5