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

[PATCH v2 4/5] Handle fast forward correctly in rebase with preserve merges

From
JSJörg Sommer <joerg@alea.gnuu.de>
Date
Mar 22, 2008, 14:08 UTC
Message-ID
<1206194907-3340-4-git-send-email-joerg@alea.gnuu.de>
In-Reply-To
<1206194907-3340-3-git-send-email-joerg@alea.gnuu.de>

Rebase-interactive with preserve merges does fast forward commits while the parent of the old commit is not the parent of the new commit. If the parent of the changed commit is not touched, e.g. has no entry in the REWRITTEN database, a fast forward happens. With these commits “A---B---C” and rebase “A---C---B” would do a fast forward for C which leads to an incorrect result.

The fast forward is also not realised, i.e. the HEAD is not updated.

After all is done, it was assumed that the new head is the rewritten old head. But if the old head was applied before current head—as in the example above—the commits after the rewritten old head are lost.

Signed-off-by: Jörg Sommer <joerg@alea.gnuu.de>
---
 git-rebase--interactive.sh |   35 ++++++++++++++++++-----------------
 1 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index e1ce44e..8626ef6 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -144,6 +144,7 @@ pick_one_preserving_merges () {
 		die "Cannot write current commit's replacement sha1"
 	fi
 
+	current_sha1=$(git rev-parse --verify HEAD)
 	# rewrite parents; if none were rewritten, we can fast-forward.
 	fast_forward=t
 	preserve=t
@@ -166,18 +167,31 @@ pick_one_preserving_merges () {
 			new_parents="$new_parents $p"
 		fi
 	done
+
+	# Don't do a fast forward, if current commit is not the parent of
+	# the new commit
+	case "$new_parents" in
+	""|" $current_sha1"*)
+		;;
+	*)
+		fast_forward=f
+		;;
+	esac
+
 	case $fast_forward in
 	t)
 		output warn "Fast forward to $sha1"
 		test $preserve = f || echo $sha1 > "$REWRITTEN"/$sha1
+		output git reset --hard $sha1
+		if test "a$1" = a-n
+		then
+			output git reset --soft $current_sha1
+		fi
 		;;
 	f)
 		test "a$1" = a-n && die "Refusing to squash a merge: $sha1"
 
 		first_parent=$(expr "$new_parents" : ' \([^ ]*\)')
-		# detach HEAD to current parent
-		output git checkout $first_parent 2> /dev/null ||
-			die "Cannot move HEAD to $first_parent"
 
 		echo $sha1 > "$DOTEST"/current-commit
 		case "$new_parents" in
@@ -330,20 +344,7 @@ do_next () {
 	HEADNAME=$(cat "$DOTEST"/head-name) &&
 	OLDHEAD=$(cat "$DOTEST"/head) &&
 	SHORTONTO=$(git rev-parse --short $(cat "$DOTEST"/onto)) &&
-	if test -d "$REWRITTEN"
-	then
-		test -f "$DOTEST"/current-commit &&
-			current_commit=$(cat "$DOTEST"/current-commit) &&
-			git rev-parse HEAD > "$REWRITTEN"/$current_commit
-		if test -f "$REWRITTEN"/$OLDHEAD
-		then
-			NEWHEAD=$(cat "$REWRITTEN"/$OLDHEAD)
-		else
-			NEWHEAD=$OLDHEAD
-		fi
-	else
-		NEWHEAD=$(git rev-parse HEAD)
-	fi &&
+	NEWHEAD=$(git rev-parse HEAD) &&
 	case $HEADNAME in
 	refs/*)
 		message="$GIT_REFLOG_ACTION: $HEADNAME onto $SHORTONTO)" &&
-- 
1.5.4.4
Previous: Jörg SommerNext: Jörg Sommer
Message 17 of 19 in “rebase with preserve merges should not show merged commits”
  1. rebase with preserve merges should not show merged commitsJörg Sommer, Mar 22, 2008
  2. Check for non‐foreign commits in rebase-interactive testJörg Sommer, Mar 22, 2008
  3. Handle fast forward correctly in rebase with preserve mergesJörg Sommer, Mar 22, 2008
  4. New tests to check rebase with preserve mergesJörg Sommer, Mar 22, 2008
  5. Johannes SchindelinMar 22, 2008
  6. Jörg SommerMar 22, 2008
  7. Johannes SchindelinMar 22, 2008
  8. Björn SteinbrinkMar 22, 2008
  9. Jörg SommerMar 22, 2008
  10. Björn SteinbrinkMar 22, 2008
  11. Jörg SommerMar 22, 2008
  12. Björn SteinbrinkMar 22, 2008
  13. Jörg SommerMar 22, 2008
  14. 1/5 rebase with preserve merges should not show merged commitsJörg Sommer, Mar 22, 2008
  15. 2/5 New test: no merges without preserve mergesJörg Sommer, Mar 22, 2008
  16. 3/5 Check for non‐foreign commits in rebase-interactive testJörg Sommer, Mar 22, 2008
  17. 4/5 Handle fast forward correctly in rebase with preserve mergesJörg Sommer, Mar 22, 2008
  18. 5/5 New tests to check rebase with preserve mergesJörg Sommer, Mar 22, 2008
  19. Johannes SchindelinMar 22, 2008

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.