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

[RFC] Interactive-rebase doesn't pick all children of "upstream"

From
Andrew Wong <andrew.kw.w@gmail.com>
Date
May 21, 2011, 05:51 UTC
Message-ID
<1305957078-19111-2-git-send-email-andrew.kw.w@gmail.com>
In-Reply-To
<1305957078-19111-1-git-send-email-andrew.kw.w@gmail.com>
Consider this graph:
        D---E    (topic, HEAD)
       /   /
  A---B---C      (master)
   \
    F            (topic2)
and the following three commands:
  1. git rebase -i A
  2. git rebase -i --onto F B
  3. git rebase -i B

Currently, (1) and (2) will pick B, D, C, and E onto A and F, respectively. However, (3) will only pick D and E onto B. This behavior of (3) is inconsistent with (1) and (2).

This also creates a bug if we do:
  4. git rebase -i C

In (4), E is never picked. And since interactive-rebase resets "HEAD" to "onto", E is lost after the interactive-rebase.

This patch fixes the inconsistency and bug by ensuring that all children of upstream are always picked.

Two of the tests contain a scenario like (3).  Since the new behavior
added more commits for picking, these tests need to be updated to edit
the "todo" list properly.
---
 git-rebase--interactive.sh               |    7 +++++--
 t/t3404-rebase-interactive.sh            |    2 +-
 t/t3411-rebase-preserve-around-merges.sh |    2 +-
 3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 41ba96a..b6d1e5b 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -711,7 +711,7 @@ then
 	# parents to rewrite and skipping dropped commits would
 	# prematurely end our probe
 	merges_option=
-	first_after_upstream="$(git rev-list --reverse --first-parent $upstream..$orig_head | head -n 1)"
+	commits_after_upstream="$(git rev-list --reverse --parents $upstream..$orig_head | sane_grep " $upstream" | cut -d' ' -s -f1)"
 else
 	merges_option="--no-merges --cherry-pick"
 fi
@@ -744,7 +744,10 @@ do
 			preserve=t
 			for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)
 			do
-				if test -f "$rewritten"/$p -a \( $p != $onto -o $sha1 = $first_after_upstream \)
+				if test -f "$rewritten"/$p && (
+					test $p != $onto ||
+					expr "$commits_after_upstream" ":" ".*$sha1.*"
+					)
 				then
 					preserve=f
 				fi
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 7d8147b..c3cddcd 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -295,7 +295,7 @@ test_expect_success 'preserve merges with -p' '
 '
 
 test_expect_success 'edit ancestor with -p' '
-	FAKE_LINES="1 edit 2 3 4" git rebase -i -p HEAD~3 &&
+	FAKE_LINES="1 2 edit 3 4" git rebase -i -p HEAD~3 &&
 	echo 2 > unrelated-file &&
 	test_tick &&
 	git commit -m L2-modified --amend unrelated-file &&
diff --git a/t/t3411-rebase-preserve-around-merges.sh b/t/t3411-rebase-preserve-around-merges.sh
index 14a23cd..ace8e54 100755
--- a/t/t3411-rebase-preserve-around-merges.sh
+++ b/t/t3411-rebase-preserve-around-merges.sh
@@ -37,7 +37,7 @@ test_expect_success 'setup' '
 #        -- C1 --
 #
 test_expect_success 'squash F1 into D1' '
-	FAKE_LINES="1 squash 3 2" git rebase -i -p B1 &&
+	FAKE_LINES="1 squash 4 2 3" git rebase -i -p B1 &&
 	test "$(git rev-parse HEAD^2)" = "$(git rev-parse C1)" &&
 	test "$(git rev-parse HEAD~2)" = "$(git rev-parse B1)" &&
 	git tag E2
-- 
1.7.5.2.316.gd7d8c.dirty
Previous: Andrew WongNext: Andrew Wong
Message 11 of 28 in “[BUG] rebase -p loses commits”
  1. Jeff KingMay 16, 2011
  2. Andrew WongMay 16, 2011
  3. Junio C HamanoMay 16, 2011
  4. Andrew WongMay 17, 2011
  5. Junio C HamanoMay 17, 2011
  6. Junio C HamanoMay 17, 2011
  7. Jeff KingMay 17, 2011
  8. Andrew WongMay 17, 2011
  9. Jeff KingMay 17, 2011
  10. [RFC] Interactive-rebase doesn't pick all children of "upstream"Andrew Wong, May 21, 2011
  11. [RFC] Interactive-rebase doesn't pick all children of "upstream"Andrew Wong, May 21, 2011
  12. Andrew WongMay 21, 2011
  13. Interactive-rebase doesn't pick all children of "upstream"Andrew Wong, Jun 5, 2011
  14. Johannes SixtJun 5, 2011
  15. Andrew WongJun 5, 2011
  16. rebase -i -p: doesn't pick certain merge commits that are children of "upstream"Andrew Wong, Jun 7, 2011
  17. rebase -i -p: doesn't pick certain merge commits that are children of "upstream"Andrew Wong, Jun 7, 2011
  18. Andrew WongJun 12, 2011
  19. Junio C HamanoJun 13, 2011
  20. Andrew WongJun 13, 2011
  21. Stephen HabermanJun 16, 2011
  22. Andrew WongJun 18, 2011
  23. Stephen HabermanJun 18, 2011
  24. Andrew WongJun 18, 2011
  25. Stephen HabermanJun 18, 2011
  26. rebase -i -p: include non-first-parent commits in todo listAndrew Wong, Jun 18, 2011
  27. Andrew WongJun 18, 2011
  28. Jeff KingMay 17, 2011

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.