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

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <git@...>
Cc: <gitster@...>, Jörg Sommer <joerg@...>
Date: Saturday, March 22, 2008 - 10:08 am

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

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Re: [PATCH] rebase with preserve merges should not show merg..., Johannes Schindelin, (Fri Mar 21, 9:33 pm)
Re: [PATCH] rebase with preserve merges should not show merg..., Johannes Schindelin, (Sat Mar 22, 7:22 am)
Re: [PATCH v2 1/5] rebase with preserve merges should not sh..., Johannes Schindelin, (Sat Mar 22, 10:46 am)
[PATCH v2 3/5] , Jörg Sommer, (Sat Mar 22, 10:08 am)
[PATCH v2 4/5] Handle fast forward correctly in rebase with ..., Jörg Sommer, (Sat Mar 22, 10:08 am)
[PATCH] , Jörg Sommer, (Fri Mar 21, 9:19 pm)
[PATCH] New tests to check rebase with preserve merges, Jörg Sommer, (Fri Mar 21, 9:19 pm)