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

[PATCH v2] rebase -i: avoid 'git reset' when possible

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Mar 3, 2009, 09:55 UTC
Message-ID
<alpine.DEB.1.00.0903031024420.6399@intel-tinevez-2-302>
In-Reply-To
<alpine.DEB.1.00.0903031008580.6399@intel-tinevez-2-302>

When picking commits whose parents have not changed, we do not need to rewrite the commit. We do not need to reset the working directory to the parent's state, either.

Requested by Sverre Rabbelier.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
	Actually, I did not think things through.  Of _course_ we need
	that rev-parse, to determine the parent of the to-be-picked
	commit.
	Changes since v1: use only one loop instead of counting the number 
	of skipped commits first, and then actually skipping them.
 git-rebase--interactive.sh    |   26 ++++++++++++++++++++++++++
 t/t3404-rebase-interactive.sh |   11 +++++++++++
 2 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 3dc659d..72f7fc7 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -442,6 +442,30 @@ do_rest () {
 	done
 }
 
+# skip picking commits whose parents are unchanged
+skip_unnecessary_picks () {
+	fd=3
+	while read command sha1 rest
+	do
+		# fd=3 means we skip the command
+		case "$fd,$command,$(git rev-parse --verify --quiet $sha1^)" in
+		3,pick,"$ONTO"*|t,p,"$ONTO"*)
+			# pick a commit whose parent is current $ONTO -> skip
+			ONTO=$sha1
+			;;
+		3,#*|3,,*)
+			# copy comments
+			;;
+		*)
+			fd=1
+			;;
+		esac
+		echo "$command${sha1:+ }$sha1${rest:+ }$rest" >&$fd
+	done < "$TODO" > "$TODO.new" 3>> "$DONE" &&
+	mv -f "$TODO".new "$TODO" ||
+	die "Could not skip unnecessary pick commands"
+}
+
 # check if no other options are set
 is_standalone () {
 	test $# -eq 2 -a "$2" = '--' &&
@@ -746,6 +770,8 @@ EOF
 		has_action "$TODO" ||
 			die_abort "Nothing to do"
 
+		test -d "$REWRITTEN" || skip_unnecessary_picks
+
 		git update-ref ORIG_HEAD $HEAD
 		output git checkout $ONTO && do_rest
 		;;
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 603b003..c32ff66 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -459,4 +459,15 @@ test_expect_success 'submodule rebase -i' '
 	FAKE_LINES="1 squash 2 3" git rebase -i A
 '
 
+test_expect_success 'avoid unnecessary reset' '
+	git checkout master &&
+	test-chmtime =123456789 file3 &&
+	git update-index --refresh &&
+	HEAD=$(git rev-parse HEAD) &&
+	git rebase -i HEAD~4 &&
+	test $HEAD = $(git rev-parse HEAD) &&
+	MTIME=$(test-chmtime -v +0 file3 | sed 's/[^0-9].*$//') &&
+	test 123456789 = $MTIME
+'
+
 test_done
-- 
1.6.2.rc1.456.g3dbe7
Previous: Johannes SchindelinNext: Johannes Sixt
Message 13 of 16 in “[RFH] rebase -i optimization”
  1. Sverre RabbelierFeb 26, 2009
  2. Johannes SchindelinFeb 26, 2009
  3. Sverre RabbelierFeb 26, 2009
  4. Johannes SchindelinFeb 27, 2009
  5. Sverre RabbelierFeb 27, 2009
  6. rebase -i: avoid 'git reset' when possibleJohannes Schindelin, Feb 27, 2009
  7. Sverre RabbelierFeb 27, 2009
  8. Johannes SchindelinFeb 27, 2009
  9. Junio C HamanoMar 1, 2009
  10. Johannes SchindelinMar 1, 2009
  11. Junio C HamanoMar 3, 2009
  12. Johannes SchindelinMar 3, 2009
  13. rebase -i: avoid 'git reset' when possibleJohannes Schindelin, Mar 3, 2009
  14. Johannes SixtMar 3, 2009
  15. Johannes SchindelinMar 3, 2009
  16. Sitaram ChamartyFeb 27, 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.