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

[PATCH] rebase -i: auto-squash commits

From
Nanako Shiraishi <nanako3@lavabit.com>
Date
Jun 17, 2009, 21:33 UTC
Message-ID
<20090618063348.6117@nanako3.lavabit.com>
In-Reply-To
<7vvdmurfao.fsf@alter.siamese.dyndns.org>

When the commit log message begins with "squash to ...", and there is a commit whose title begins with the same ..., automatically modify the todo list of rebase -i so that the commit marked for squashing come right after the commit to be modified, and change the action of the moved commit from pick to squash.

Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>
---
  Quoting Junio C Hamano <gitster@pobox.com>:
  I think you meant --amend, but it often happens to me that after preparing
  a three-patch series:
  
      [1/3] Clean up the surrounding code I will touch
      [2/3] Lay the groundwork
      [3/3] Implement a cool new feature
  
  I find that there are more clean-up that should have been done in [1/3].
  The way "rebase -i" expects me to work is:
  
      $ edit ;# more clean-ups
      $ git commit -a -m 'squash to "clean up"'
      $ git rebase -i HEAD~5
  
  which will give me
          
      pick 1/3 Clean up ...
      pick 2/3 Lay the groundwork
      pick 3/3 Implement
      pick 4/3 squash to "clean up"
  
  that I'll change to 
  
      pick 1/3 Clean up ...
      squash 4/3 squash to "clean up"
      pick 2/3 Lay the groundwork
      pick 3/3 Implement
  
  and then I'll need to edit the commit message for the first two combined.

How about this patch? It does not let you say 'squash to "clean up"' but other people who are more skillfull than me can enhance such details.

 git-rebase--interactive.sh   |   31 +++++++++++++++++++++++++++++++
 t/t3414-rebase-autosquash.sh |   36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+), 0 deletions(-)
 create mode 100755 t/t3414-rebase-autosquash.sh
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index f96d887..0832164 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -482,6 +482,35 @@ get_saved_options () {
 	test -f "$DOTEST"/rebase-root && REBASE_ROOT=t
 }
 
+# Rearrange the todo list that has both "pick sha1 msg" and
+# "pick sha1 squash to msg" in it, so that the latter comes
+# immediately after the former, and change "pick" to "squash".
+rearrange_squash () {
+	sed -n -e 's/^pick \([0-9a-f]*\) squash to /\1 /p' "$1" >"$1.sq"
+	test -s "$1.sq" || return
+
+	used=
+	while read pick sha1 message
+	do
+		case " $used" in
+		*" $sha1 "*) continue ;;
+		esac
+		echo "$pick $sha1 $message"
+		while read squash msg
+		do
+			case "$message" in
+			"$msg"*)
+				echo "squash $squash to $msg"
+				used="$used$squash "
+				break
+				;;
+			esac
+		done <"$1.sq"
+	done <"$1" >"$1.rearranged"
+
+	cat "$1.rearranged" >"$1"
+}
+
 while test $# != 0
 do
 	case "$1" in
@@ -746,6 +776,7 @@ first and then run 'git rebase --continue' again."
 		fi
 
 		test -s "$TODO" || echo noop >> "$TODO"
+		rearrange_squash "$TODO"
 		cat >> "$TODO" << EOF
 
 # Rebase $SHORTREVISIONS onto $SHORTONTO
diff --git a/t/t3414-rebase-autosquash.sh b/t/t3414-rebase-autosquash.sh
new file mode 100755
index 0000000..ddb0daf
--- /dev/null
+++ b/t/t3414-rebase-autosquash.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+test_description='auto squash'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+	echo 0 > file0
+	git add .
+	test_tick
+	git commit -m "initial commit"
+	echo 0 > file1
+	echo 2 > file2
+	git add .
+	test_tick
+	git commit -m "first commit"
+	echo 3 > file3
+	git add .
+	test_tick
+	git commit -m "second commit"
+'
+
+test_expect_success 'auto squash' '
+	echo 1 > file1
+	git add -u
+	test_tick
+	git commit -m "squash to first"
+	git tag final
+	test_tick
+	git rebase -i HEAD^^^
+	git log --oneline >actual
+	test 3 = $(wc -l <actual) &&
+	git diff --exit-code final
+'
+
+test_done
-- 
1.6.2.GIT

-- 
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
Previous: MintyNext: Johannes Schindelin
Message 11 of 40 in “git rebase --interactive squash/squish/fold/rollup”
  1. MintyJun 17, 2009
  2. John TapsellJun 17, 2009
  3. MintyJun 17, 2009
  4. Junio C HamanoJun 17, 2009
  5. John TapsellJun 17, 2009
  6. Paolo BonziniJun 17, 2009
  7. John KoleszarJun 17, 2009
  8. John TapsellJun 17, 2009
  9. Clemens BuchacherJun 17, 2009
  10. MintyJun 18, 2009
  11. rebase -i: auto-squash commitsNanako Shiraishi, Jun 17, 2009
  12. Johannes SchindelinJun 17, 2009
  13. Re: rebase -i: auto-squash commitsNicolas Sebrecht, Jun 18, 2009
  14. Junio C HamanoJun 18, 2009
  15. Johannes SchindelinJun 18, 2009
  16. Jakub NarebskiJun 18, 2009
  17. Junio C HamanoJun 18, 2009
  18. Johannes SchindelinJun 18, 2009
  19. Teemu LikonenJun 18, 2009
  20. Johannes SchindelinJun 18, 2009
  21. Teemu LikonenJun 18, 2009
  22. Johannes SchindelinJun 18, 2009
  23. Jakub NarebskiJun 18, 2009
  24. John KoleszarJun 18, 2009
  25. Junio C HamanoJun 18, 2009
  26. Johannes SchindelinJun 18, 2009
  27. Michael J GruberJun 18, 2009
  28. Miles BaderJun 19, 2009
  29. Re: rebase -i: auto-squash commitsNicolas Sebrecht, Jun 18, 2009
  30. Matthieu MoyJun 18, 2009
  31. Johannes SchindelinJun 18, 2009
  32. Matthieu MoyJun 18, 2009
  33. Re: rebase -i: auto-squash commitsNicolas Sebrecht, Jun 18, 2009
  34. Junio C HamanoJun 18, 2009
  35. rebase -i --autosquash: auto-squash commitsNanako Shiraishi, Jun 18, 2009
  36. Alex RiesenJun 18, 2009
  37. Wincent ColaiutaJun 19, 2009
  38. Nanako ShiraishiJun 20, 2009
  39. Michael HaggertyJun 18, 2009
  40. Junio C HamanoJun 18, 2009

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.