git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] Allow rebase to run if upstream is completely merged

From
Johannes Sixt <johannes.sixt@telecom.at>
Date
Jul 4, 2007, 20:09 UTC
Message-ID
<200707042209.10877.johannes.sixt@telecom.at>
Consider this history:
  o--o-...-B          <- origin
      \     \
       x--x--M--x--x  <- master

In this situation, rebase considers master fully up-to-date and would not do anything. However, if there were additional commits on origin, the rebase would run and move the commits x on top of origin.

Here we change rebase to short-circuit out only if the history since origin is strictly linear. Consequently, the above as well as a history like this would be linearized:

  o--o               <- origin
      \
       x--x
        \  \
         x--M--x--x  <- master
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
 git-rebase.sh     |    8 +++++---
 t/t3400-rebase.sh |   39 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/git-rebase.sh b/git-rebase.sh
index c590661..7a02f29 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -305,10 +305,12 @@ branch=$(git rev-parse --verify "${branch_name}^0") || exit
 
 # Now we are rebasing commits $upstream..$branch on top of $onto
 
-# Check if we are already based on $onto, but this should be
-# done only when upstream and onto are the same.
+# Check if we are already based on $onto with linear history,
+# but this should be done only when upstream and onto are the same.
 mb=$(git merge-base "$onto" "$branch")
-if test "$upstream" = "$onto" && test "$mb" = "$onto"
+if test "$upstream" = "$onto" && test "$mb" = "$onto" &&
+	# linear history?
+	! git rev-list --parents "$onto".."$branch" | grep " .* " > /dev/null
 then
 	echo >&2 "Current branch $branch_name is up to date."
 	exit 0
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index 95f3a2a..62205b2 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -12,7 +12,7 @@ This test runs git rebase and checks that the author information is not lost.
 export GIT_AUTHOR_EMAIL=bogus_email_address
 
 test_expect_success \
-    'prepare repository with topic branch, then rebase against master' \
+    'prepare repository with topic branches' \
     'echo First > A &&
      git update-index --add A &&
      git-commit -m "Add A." &&
@@ -24,11 +24,48 @@ test_expect_success \
      echo Third >> A &&
      git update-index A &&
      git-commit -m "Modify A." &&
+     git checkout -b side my-topic-branch &&
+     echo Side >> C &&
+     git add C &&
+     git commit -m "Add C" &&
+     git checkout -b nonlinear my-topic-branch &&
+     echo Edit >> B &&
+     git add B &&
+     git commit -m "Modify B" &&
+     git merge side &&
+     git checkout -b upstream-merged-nonlinear &&
+     git merge master &&
      git checkout -f my-topic-branch &&
+     git tag topic
+'
+
+test_expect_success 'rebase against master' '
      git rebase master'
 
 test_expect_failure \
     'the rebase operation should not have destroyed author information' \
     'git log | grep "Author:" | grep "<>"'
 
+test_expect_success 'rebase after merge master' '
+     git reset --hard topic &&
+     git merge master &&
+     git rebase master &&
+     ! git show | grep "^Merge:"
+'
+
+test_expect_success 'rebase of history with merges is linearized' '
+     git checkout nonlinear &&
+     test 4 = $(git rev-list master.. | wc -l) &&
+     git rebase master &&
+     test 3 = $(git rev-list master.. | wc -l)
+'
+
+test_expect_success \
+    'rebase of history with merges after upstream merge is linearized' '
+     git checkout upstream-merged-nonlinear &&
+     test 5 = $(git rev-list master.. | wc -l) &&
+     git rebase master &&
+     test 3 = $(git rev-list master.. | wc -l)
+'
+
 test_done
-- 
1.5.3.rc0
Message 1 of 1 in “Allow rebase to run if upstream is completely merged”
  1. Allow rebase to run if upstream is completely mergedJohannes Sixt, Jul 4, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.