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

[PATCH] Test that the 'rebase -i' "reword" command always cherry-picks a commit.

From
Marc Branchaud <marcnarc@xiplink.com>
Date
Mar 22, 2010, 19:25 UTC
Message-ID
<1269285942-17496-1-git-send-email-marcnarc@xiplink.com>
In-Reply-To
<4BA11B23.4090801@xiplink.com>

In particular, "reword" should cherry-pick a reworded commit even if the commit's message is unchanged.

This behaviour provides a way to deal with a situation that can arise when a merge had to be reverted. Added an addendum to revert-a-faulty-merge.txt describing the situation and how to use "reword" to handle it. ---

Is this more acceptable than adding --no-ff to rebase--interactive?

I wasn't sure how to integrate the new text into revert-a-faulty-merge.txt. I went with an addendum, but I'm open to other approaches.

		M.
 Documentation/howto/revert-a-faulty-merge.txt |   64 +++++++++++++++++++++++++
 t/t3417-rebase-reword-forces-cherry-pick.sh   |   59 +++++++++++++++++++++++
 2 files changed, 123 insertions(+), 0 deletions(-)
 create mode 100755 t/t3417-rebase-reword-forces-cherry-pick.sh
diff --git a/Documentation/howto/revert-a-faulty-merge.txt b/Documentation/howto/revert-a-faulty-merge.txt
index 3b4a390..892433d 100644
--- a/Documentation/howto/revert-a-faulty-merge.txt
+++ b/Documentation/howto/revert-a-faulty-merge.txt
@@ -142,6 +142,8 @@ different resolution strategies:
    revert of a merge was rebuilt from scratch (i.e. rebasing and fixing,
    as you seem to have interpreted), then re-merging the result without
    doing anything else fancy would be the right thing to do.
+   (See the ADDENDUM below for how to rebuild a branch from scratch
+   without changing its original branching-off point.)
 
 However, there are things to keep in mind when reverting a merge (and
 reverting such a revert).
@@ -177,3 +179,65 @@ the answer is: "oops, I really shouldn't have merged it, because it wasn't
 ready yet, and I really need to undo _all_ of the merge"). So then you
 really should revert the merge, but when you want to re-do the merge, you
 now need to do it by reverting the revert.
+
+ADDENDUM
+
+Sometimes you're in a situation like this
+
+ P---o---o---M---x---x---W---x
+  \         /
+   A---B---C
+
+where you:
+
+ - Need to rewrite one of the commits on the A-B-C branch; and
+
+ - Want the rewritten A-B-C branch to still start at commit P (perhaps P
+   is a branching-off point for yet another branch, and you want be able to
+   merge A-B-C into both branches).
+
+The natural thing to do in this case is to checkout the A-B-C branch and use
+"rebase -i A" to change commit B.  However, this does not rewrite commit A,
+and you end up with this:
+
+ P---o---o---M---x---x---W---x
+  \         /
+   A---B---C   <-- old branch
+   \
+    B'---C'    <-- rewritten branch
+
+To merge A-B'-C' into the mainline branch you would still have to first revert
+commit W in order to pick up the changes in A, but then it's likely that the
+changes in B' will conflict with the original B changes re-introduced by the
+reversion of W.
+
+However, you could avoid these problems if you recreated the entire branch,
+including commit A:
+
+ P---o---o---M---x---x---W---x
+ |\         /
+ | A---B---C   <-- old branch
+ \
+  A'---B'---C' <-- entirely recreated branch
+
+Now you can merge A'-B'-C' into the mainline branch without worrying about
+first reverting W.
+
+But if you don't actually need to change commit A, then you need some way to
+recreate it as a new commit with the same changes in it.  One way to do this
+is to use the "reword" command in "rebase -i".  If you:
+
+ - Checkout the A-B-C branch
+
+ - Run "rebase -i P" to rebase the entire branch
+
+ - "reword" commit A (the first commit in the rebase script)
+
+ - Make NO changes to commit A's message
+
+then you'll end up with a new branch A'-B'-C' with all-new commits (all the
+SHA IDs will be different) but that has the same changes that were in the
+original A-B-C branch.
+
+You can then modify commit B' as you like and merge the new A'-B''-C' branch
+into the mainline branch without first reverting commit W.
diff --git a/t/t3417-rebase-reword-forces-cherry-pick.sh b/t/t3417-rebase-reword-forces-cherry-pick.sh
new file mode 100755
index 0000000..3e29f0f
--- /dev/null
+++ b/t/t3417-rebase-reword-forces-cherry-pick.sh
@@ -0,0 +1,59 @@
+#!/bin/sh
+#
+# Copyright (c) 2010 Marc Branchaud
+#
+
+test_description='git rebase interactive "reword" always forces cherry-pick
+
+This test ensures that the "reword" command of "git rebase -i" cherry-picks
+a reworded commit even if no changes are made to the commit message.
+
+This behaviour provides a way to deal with a situation that can arise when a
+merge had to be reverted.  For details, see the ADDENDUM in
+Documentation/howto/revert-a-faulty-merge.txt.
+'
+
+. ./test-lib.sh
+
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+set_fake_editor
+
+# A simple linear history.
+test_expect_success 'setup' '
+	test_commit A file1 &&
+	test_commit B file1 &&
+	test_commit C file1 &&
+	test_commit D file1 &&
+	git branch old-master HEAD
+'
+
+# Ensure that the rebased commits get a different timestamp.
+test_tick
+
+# Reword the first commit, but don't actually change the message
+test_expect_success 'reword' '
+	FAKE_LINES="reword 1 2 3" git rebase -i A
+'
+
+# There should be no textual differences between the old and new branches.
+# However:
+#  - Commit A should be completely unchanged.
+#  - Commits B, C and D should have different SHA IDs.
+test_expect_success 'verify' '
+	touch empty &&
+	test ! $(git rev-parse ) = $(git rev-parse master) &&
+	git diff old-master master > out &&
+	test_cmp empty out &&
+	test ! $(git rev-parse C) = $(git rev-parse master^) &&
+	git diff old-master^ master^ > out &&
+	test_cmp empty out &&
+	test ! $(git rev-parse B) = $(git rev-parse master^^) &&
+	git diff old-master^^ master^^ > out &&
+	test_cmp empty out &&
+	test $(git rev-parse A) = $(git rev-parse master^^^) &&
+	git diff old-master^^^ master^^^ > out &&
+	test_cmp empty out
+'
+
+test_done
-- 
1.7.0.3
Previous: Marc BranchaudNext: Avery Pennarun
Message 14 of 32 in “Teach --no-ff option to 'rebase -i'.”
  1. Teach --no-ff option to 'rebase -i'.Marc Branchaud, Mar 16, 2010
  2. Marc BranchaudMar 16, 2010
  3. [PATCHv2] Teach --no-ff option to 'rebase -i'.Marc Branchaud, Mar 16, 2010
  4. Jonathan NiederMar 16, 2010
  5. Johannes SixtMar 17, 2010
  6. Peter BaumannMar 17, 2010
  7. Johannes SixtMar 17, 2010
  8. Peter BaumannMar 17, 2010
  9. Johannes SixtMar 18, 2010
  10. Peter BaumannMar 18, 2010
  11. Marc BranchaudMar 17, 2010
  12. Johannes SixtMar 17, 2010
  13. Marc BranchaudMar 17, 2010
  14. Test that the 'rebase -i' "reword" command always cherry-picks a commit.Marc Branchaud, Mar 22, 2010
  15. Avery PennarunMar 22, 2010
  16. Marc BranchaudMar 22, 2010
  17. Junio C HamanoMar 22, 2010
  18. Marc BranchaudMar 23, 2010
  19. [PATCHv3] Teach -f/--force-rebase option to 'rebase -i'.Marc Branchaud, Mar 23, 2010
  20. Junio C HamanoMar 23, 2010
  21. 0/2 Teach the --no-ff option to 'rebase -i'.Marc Branchaud, Mar 24, 2010
  22. Junio C HamanoMar 24, 2010
  23. [PATCHv5] Teach rebase the --no-ff option.Marc Branchaud, Mar 24, 2010
  24. Junio C HamanoMar 24, 2010
  25. 1/2 Teach 'rebase -i' to accept and ignore the -f/--force-rebase option.Marc Branchaud, Mar 24, 2010
  26. 2/2 Teach the --no-ff option to 'rebase -i'.Marc Branchaud, Mar 24, 2010
  27. Junio C HamanoMar 24, 2010
  28. Jonathan NiederMar 23, 2010
  29. Jonathan NiederMar 22, 2010
  30. Marc BranchaudMar 17, 2010
  31. Jonathan NiederMar 17, 2010
  32. Jonathan NiederMar 17, 2010

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.