{"thread":{"id":"8868","subject":"[PATCH] Allow rebase to run if upstream is completely merged","startedAt":"2007-07-04T20:09:10Z","lastAt":"2007-07-04T20:09:10Z","messageCount":1,"participants":["Johannes Sixt"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"46509","messageId":"200707042209.10877.johannes.sixt@telecom.at","threadId":"8868","inReplyTo":null,"subject":"[PATCH] Allow rebase to run if upstream is completely merged","fromName":"Johannes Sixt","fromEmail":"johannes.sixt@telecom.at","sentAt":"2007-07-04T20:09:10Z","receivedAt":"2007-07-04T20:09:10Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Consider this history:\n\n  o--o-...-B          <- origin\n      \\     \\\n       x--x--M--x--x  <- master\n\nIn this situation, rebase considers master fully up-to-date and would\nnot do anything. However, if there were additional commits on origin,\nthe rebase would run and move the commits x on top of origin.\n\nHere we change rebase to short-circuit out only if the history since origin\nis strictly linear. Consequently, the above as well as a history like this\nwould be linearized:\n\n  o--o               <- origin\n      \\\n       x--x\n        \\  \\\n         x--M--x--x  <- master\n\n\nSigned-off-by: Johannes Sixt <johannes.sixt@telecom.at>\n---\n git-rebase.sh     |    8 +++++---\n t/t3400-rebase.sh |   39 ++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 43 insertions(+), 4 deletions(-)\n\ndiff --git a/git-rebase.sh b/git-rebase.sh\nindex c590661..7a02f29 100755\n--- a/git-rebase.sh\n+++ b/git-rebase.sh\n@@ -305,10 +305,12 @@ branch=$(git rev-parse --verify \"${branch_name}^0\") || exit\n \n # Now we are rebasing commits $upstream..$branch on top of $onto\n \n-# Check if we are already based on $onto, but this should be\n-# done only when upstream and onto are the same.\n+# Check if we are already based on $onto with linear history,\n+# but this should be done only when upstream and onto are the same.\n mb=$(git merge-base \"$onto\" \"$branch\")\n-if test \"$upstream\" = \"$onto\" && test \"$mb\" = \"$onto\"\n+if test \"$upstream\" = \"$onto\" && test \"$mb\" = \"$onto\" &&\n+\t# linear history?\n+\t! git rev-list --parents \"$onto\"..\"$branch\" | grep \" .* \" > /dev/null\n then\n \techo >&2 \"Current branch $branch_name is up to date.\"\n \texit 0\ndiff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh\nindex 95f3a2a..62205b2 100755\n--- a/t/t3400-rebase.sh\n+++ b/t/t3400-rebase.sh\n@@ -12,7 +12,7 @@ This test runs git rebase and checks that the author information is not lost.\n export GIT_AUTHOR_EMAIL=bogus_email_address\n \n test_expect_success \\\n-    'prepare repository with topic branch, then rebase against master' \\\n+    'prepare repository with topic branches' \\\n     'echo First > A &&\n      git update-index --add A &&\n      git-commit -m \"Add A.\" &&\n@@ -24,11 +24,48 @@ test_expect_success \\\n      echo Third >> A &&\n      git update-index A &&\n      git-commit -m \"Modify A.\" &&\n+     git checkout -b side my-topic-branch &&\n+     echo Side >> C &&\n+     git add C &&\n+     git commit -m \"Add C\" &&\n+     git checkout -b nonlinear my-topic-branch &&\n+     echo Edit >> B &&\n+     git add B &&\n+     git commit -m \"Modify B\" &&\n+     git merge side &&\n+     git checkout -b upstream-merged-nonlinear &&\n+     git merge master &&\n      git checkout -f my-topic-branch &&\n+     git tag topic\n+'\n+\n+test_expect_success 'rebase against master' '\n      git rebase master'\n \n test_expect_failure \\\n     'the rebase operation should not have destroyed author information' \\\n     'git log | grep \"Author:\" | grep \"<>\"'\n \n+test_expect_success 'rebase after merge master' '\n+     git reset --hard topic &&\n+     git merge master &&\n+     git rebase master &&\n+     ! git show | grep \"^Merge:\"\n+'\n+\n+test_expect_success 'rebase of history with merges is linearized' '\n+     git checkout nonlinear &&\n+     test 4 = $(git rev-list master.. | wc -l) &&\n+     git rebase master &&\n+     test 3 = $(git rev-list master.. | wc -l)\n+'\n+\n+test_expect_success \\\n+    'rebase of history with merges after upstream merge is linearized' '\n+     git checkout upstream-merged-nonlinear &&\n+     test 5 = $(git rev-list master.. | wc -l) &&\n+     git rebase master &&\n+     test 3 = $(git rev-list master.. | wc -l)\n+'\n+\n test_done\n-- \n1.5.3.rc0\n"}]}