From: Stephen Haberman Date: Tue, 24 Jun 2008 17:14:22 +0000 (-0500) Subject: Convert prefer-rebase to update. X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=eb008c5d4f6cd842778313f56c82cdd76de0863e;p=git-central.git Convert prefer-rebase to update. --- diff --git a/cbas/update b/cbas/update index 9e1bf09..c12e8ef 100755 --- a/cbas/update +++ b/cbas/update @@ -1,4 +1,9 @@ #!/bin/sh -. /srv/git/hooks/server/update-no-rewind +refname="$1" +oldrev="$2" +newrev="$3" + +/srv/git/hooks/server/update-no-rewind "$refname" "$oldrev" "$newrev" && +/srv/git/hooks/server/update-prefer-rebase "$refname" "$oldrev" "$newrev" diff --git a/server/pre-receive-prefer-rebase b/server/pre-receive-prefer-rebase deleted file mode 100644 index 423f253..0000000 --- a/server/pre-receive-prefer-rebase +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/sh - -while read oldrev newrev refname ; do - if expr "$oldrev" : '0*$' >/dev/null ; then - exit 0 - fi - - # 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 - # - # 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 - # - # 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 - # - # 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 - - git rev-parse --not --branches | grep -v $(git rev-parse $refname) | git rev-list --stdin $oldrev..$newrev | while read commit ; do - number_of_parents=$(git rev-list -n 1 --parents $commit | sed 's/ /\n/g' | grep -v $commit | wc -l) - if [[ $number_of_parents > 1 ]] ; then - # Find the original branch point (B) - parents=$(git rev-list -n 1 --parents $commit | sed 's/ /\n/g' | grep -v $commit) - baserev=$(git merge-base $parents) - - # For each parent - git rev-list -n 1 --parents $commit | sed 's/ /\n/g' | grep -v $commit | while read parent ; do - all_commits=$(git rev-list $baserev..$parent | wc -l) - new_commits=$(git rev-parse --not --branches | git rev-list --stdin $baserev..$parent | wc -l) - if [[ $all_commits -eq $new_commits ]] ; then - echo "----------------------------------------------------" - echo - echo "It looks like you should rebase instead of merging $commit" - echo - echo "----------------------------------------------------" - exit 1 - fi - done - if [ $? -ne 0 ] ; then - exit 1 - fi - fi - done - if [ $? -ne 0 ] ; then - exit 1 - fi -done - diff --git a/server/update-prefer-rebase b/server/update-prefer-rebase new file mode 100644 index 0000000..f46f5f2 --- /dev/null +++ b/server/update-prefer-rebase @@ -0,0 +1,37 @@ +#!/bin/sh + +# Command line +refname="$1" +oldrev="$2" +newrev="$3" + +if expr "$oldrev" : '0*$' >/dev/null ; then + exit 0 +fi + +git rev-parse --not --branches | git rev-list --stdin $oldrev..$newrev | while read commit ; do + number_of_parents=$(git rev-list -n 1 --parents $commit | sed 's/ /\n/g' | grep -v $commit | wc -l) + if [[ $number_of_parents > 1 ]] ; then + # Find the original branch point (B) + parents=$(git rev-list -n 1 --parents $commit | sed 's/ /\n/g' | grep -v $commit) + baserev=$(git merge-base $parents) + + # For each parent + git rev-list -n 1 --parents $commit | sed 's/ /\n/g' | grep -v $commit | while read parent ; do + all_commits=$(git rev-list $baserev..$parent | wc -l) + new_commits=$(git rev-parse --not --branches | git rev-list --stdin $baserev..$parent | wc -l) + if [[ $all_commits -eq $new_commits ]] ; then + echo "----------------------------------------------------" + echo + echo "It looks like you should rebase instead of merging $commit" + echo + echo "----------------------------------------------------" + exit 1 + fi + done + if [ $? -ne 0 ] ; then + exit 1 + fi + fi +done + diff --git a/tests/t2300-server-pre-receive-prefer-rebase.sh b/tests/t2300-server-pre-receive-prefer-rebase.sh deleted file mode 100644 index e13d155..0000000 --- a/tests/t2300-server-pre-receive-prefer-rebase.sh +++ /dev/null @@ -1,111 +0,0 @@ -#!/bin/sh - -test_description='server pre-receive 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_server_hook 'pre-receive-prefer-rebase' 'pre-receive' - -test_expect_success 'all local changes do not need a merge' ' - # 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) && - - ! 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 '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 - diff --git a/tests/t2300-server-update-prefer-rebase.sh b/tests/t2300-server-update-prefer-rebase.sh new file mode 100644 index 0000000..4e9d4fa --- /dev/null +++ b/tests/t2300-server-update-prefer-rebase.sh @@ -0,0 +1,111 @@ +#!/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_server_hook 'update-prefer-rebase' 'update' + +test_expect_success 'all local changes do not need a merge' ' + # 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) && + + ! 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 '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 +