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

[PATCH 6/7] add support for creating equal tree markers after rebase

From
BLBernhard R. Link <brlink@debian.org>
Date
Nov 30, 2009, 14:45 UTC
Message-ID
<07307f70f21343d69765c783dc82215ce52a3432.1259524136.git.brlink@debian.org>
In-Reply-To
<cover.1259524136.git.brlink@debian.org>

With the new --eqt option, git rebase adds an equal tree marker, so that the old branch can be fast-forwarded to the new one. If the trees are not equal, a fake merge of the new base and the old branch is created first.

TODO:
 - manpage update,
 - should --eqt have a better (longer more descriptive) name?
 - the commit message of the merge should have a better default
   and presented to the user for editing
---
 git-rebase.sh |   33 +++++++++++++++++++++++++++++++--
 1 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/git-rebase.sh b/git-rebase.sh
index 391f6d6..681c97b 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -50,6 +50,7 @@ diffstat=$(git config --bool rebase.stat)
 git_am_opt=
 rebase_root=
 force_rebase=
+equal_tree_marker=
 
 continue_merge () {
 	test -n "$prev_head" || die "prev_head must be defined"
@@ -132,11 +133,30 @@ call_merge () {
 	esac
 }
 
+# is there really no already existing function for this?
+tree_of_commit() {
+        git cat-file commit "$1" | grep '^tree ' | head -n 1 | sed -e 's/^tree //'
+}
+
 move_to_original_branch () {
 	test -z "$head_name" &&
 		head_name="$(cat "$dotest"/head-name)" &&
 		onto="$(cat "$dotest"/onto)" &&
-		orig_head="$(cat "$dotest"/orig-head)"
+		orig_head="$(cat "$dotest"/orig-head)" &&
+		equal_tree_marker="$(cat "$dotest"/eqt)"
+	if test t = "$equal_tree_marker" ; then
+		# first apply all the changes to the old branch
+		old_tree=$(tree_of_commit "$orig_head")
+		new_tree=$(tree_of_commit HEAD)
+		if test "$old_tree" = "$new_tree" ; then
+			old_branch="$orig_head"
+		else
+			# TODO: better commit message
+			old_branch=$(echo "rebase $head_name onto $onto" | git-commit-tree $new_tree -p "$orig_head" -p "$onto" )
+		fi
+		# then say the old branch can be upgraded to the new one:
+		git equal-tree-marker "$old_branch"
+	fi
 	case "$head_name" in
 	refs/*)
 		message="rebase finished: $head_name onto $onto"
@@ -220,6 +240,7 @@ do
 			end=$(cat "$dotest/end")
 			msgnum=$(cat "$dotest/msgnum")
 			onto=$(cat "$dotest/onto")
+			equal_tree_marker=$(cat "$dotest/eqt")
 			GIT_QUIET=$(cat "$dotest/quiet")
 			continue_merge
 			while test "$msgnum" -le "$end"
@@ -234,6 +255,7 @@ do
 		onto=$(cat "$GIT_DIR"/rebase-apply/onto) &&
 		orig_head=$(cat "$GIT_DIR"/rebase-apply/orig-head) &&
 		GIT_QUIET=$(cat "$GIT_DIR"/rebase-apply/quiet)
+		equal_tree_marker=$(cat "$GIT_DIR"/rebase-apply/eqt)
 		git am --resolved --3way --resolvemsg="$RESOLVEMSG" &&
 		move_to_original_branch
 		exit
@@ -251,6 +273,7 @@ do
 			msgnum=$(cat "$dotest/msgnum")
 			msgnum=$(($msgnum + 1))
 			onto=$(cat "$dotest/onto")
+			equal_tree_marker=$(cat "$dotest/eqt")
 			GIT_QUIET=$(cat "$dotest/quiet")
 			while test "$msgnum" -le "$end"
 			do
@@ -264,6 +287,7 @@ do
 		onto=$(cat "$GIT_DIR"/rebase-apply/onto) &&
 		orig_head=$(cat "$GIT_DIR"/rebase-apply/orig-head) &&
 		GIT_QUIET=$(cat "$GIT_DIR"/rebase-apply/quiet)
+		equal_tree_marker=$(cat "$GIT_DIR"/rebase-apply/eqt)
 		git am -3 --skip --resolvemsg="$RESOLVEMSG" &&
 		move_to_original_branch
 		exit
@@ -340,6 +364,9 @@ do
 		git_am_opt="$git_am_opt $1"
 		force_rebase=t
 		;;
+	--eqt)
+		equal_tree_marker=t
+		;;
 	-C*)
 		git_am_opt="$git_am_opt $1"
 		;;
@@ -522,7 +549,8 @@ then
 		echo $head_name > "$GIT_DIR"/rebase-apply/head-name &&
 		echo $onto > "$GIT_DIR"/rebase-apply/onto &&
 		echo $orig_head > "$GIT_DIR"/rebase-apply/orig-head &&
-		echo "$GIT_QUIET" > "$GIT_DIR"/rebase-apply/quiet
+		echo "$GIT_QUIET" > "$GIT_DIR"/rebase-apply/quiet &&
+		echo "$equal_tree_marker" > "$GIT_DIR"/rebase-apply/eqt
 	exit $ret
 fi
 
@@ -537,6 +565,7 @@ echo "$prev_head" > "$dotest/prev_head"
 echo "$orig_head" > "$dotest/orig-head"
 echo "$head_name" > "$dotest/head-name"
 echo "$GIT_QUIET" > "$dotest/quiet"
+echo "$equal_tree_marker" > "$dotest/eqt"
 
 msgnum=0
 for cmt in `git rev-list --reverse --first-equal-tree-only --no-merges "$revisions"`
Previous: Bernhard R. LinkNext: Bernhard R. Link
Message 8 of 29 in “equal-tree-merges as way to make rebases fast-forward-able”
  1. Bernhard R. LinkNov 30, 2009
  2. 1/7 add new command git equal-tree-markerBernhard R. Link, Nov 30, 2009
  3. Michael J GruberNov 30, 2009
  4. 2/7 add option to only visit the first parent of a equal tree mergeBernhard R. Link, Nov 30, 2009
  5. 3/7 format-patch defaults to --first-equal-tree-onlyBernhard R. Link, Nov 30, 2009
  6. 4/7 support equal tree merges in interactive rebaseBernhard R. Link, Nov 30, 2009
  7. 5/7 make rebase -m equal tree marker awareBernhard R. Link, Nov 30, 2009
  8. 6/7 add support for creating equal tree markers after rebaseBernhard R. Link, Nov 30, 2009
  9. 7/7 add support for creating equal tree markers to rebase -iBernhard R. Link, Nov 30, 2009
  10. Sverre RabbelierNov 30, 2009
  11. Paolo BonziniNov 30, 2009
  12. Bernhard R. LinkNov 30, 2009
  13. Michael J GruberNov 30, 2009
  14. Michael J GruberNov 30, 2009
  15. Bernhard R. LinkNov 30, 2009
  16. Johannes SchindelinNov 30, 2009
  17. Junio C HamanoNov 30, 2009
  18. Bernhard R. LinkNov 30, 2009
  19. Junio C HamanoDec 1, 2009
  20. Johannes SixtNov 30, 2009
  21. Junio C HamanoNov 30, 2009
  22. Nanako ShiraishiNov 30, 2009
  23. Junio C HamanoDec 1, 2009
  24. git-merge: a deprecation notice of the ancient command line syntaxJunio C Hamano, Dec 1, 2009
  25. Nicolas PitreDec 1, 2009
  26. Junio C HamanoDec 1, 2009
  27. Nanako ShiraishiDec 2, 2009
  28. Junio C HamanoDec 2, 2009
  29. Michael HaggertyDec 1, 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.