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

[PATCH 11/11] Improve merge performance by avoiding in-index merges.

From
Shawn O. Pearce <spearce@spearce.org>
Date
Dec 28, 2006, 07:35 UTC
Message-ID
<20061228073534.GK17867@spearce.org>
In-Reply-To
<9847899e4ba836980dbfed6d0ea1c82f31f21456.1167290864.git.spearce@spearce.org>

In the early days of Git we performed a 3-way read-tree based merge before attempting any specific merge strategy, as our core merge strategies of merge-one-file and merge-recursive were slower script based programs which took far longer to execute. This was a good performance optimization in the past, as most merges were able to be handled strictly by `read-tree -m -u`.

However now that merge-recursive is a C based program which performs a full 3-way read-tree before it starts running we need to pay the cost of the 3-way read-tree twice if we have to do any sort of file level merging. This slows down some classes of simple merges which `read-tree -m -u` could not handle but which merge-recursive does automatically.

For a really trivial merge which can be handled entirely by `read-tree -m -u`, skipping the read-tree and just going directly into merge-recursive saves on average 50 ms on my PowerPC G4 system. May sound odd, but it does appear to be true.

In a really simple merge which needs to use merge-recursive to handle a file that was modified on both branches, skipping the read-tree in git-merge saves on average almost 100 ms (on the same PowerPC G4) as we avoid doing some work twice.

We only avoid `read-tree -m -u` if the only strategy to use is merge-recursive, as not all merge strategies perform as well as merge-recursive does.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 git-merge.sh |   39 ++++++++++++++++++++++-----------------
 1 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/git-merge.sh b/git-merge.sh
index a8f673e..74d4fb0 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -341,23 +341,28 @@ f,*)
 ?,1,*,)
 	# We are not doing octopus, not fast forward, and have only
 	# one common.  See if it is really trivial.
-	git var GIT_COMMITTER_IDENT >/dev/null || exit
-
-	echo "Trying really trivial in-index merge..."
-	git-update-index --refresh 2>/dev/null
-	if git-read-tree --trivial -m -u -v $common $head "$1" &&
-	   result_tree=$(git-write-tree)
-	then
-	    echo "Wonderful."
-	    result_commit=$(
-	        echo "$merge_msg" |
-	        git-commit-tree $result_tree -p HEAD -p "$1"
-	    ) || exit
-	    finish "$result_commit" "In-index merge"
-	    dropsave
-	    exit 0
-	fi
-	echo "Nope."
+	case "$use_strategies" in
+	recursive|'recursive '|recur|'recur ')
+		: run merge later
+		;;
+	*)
+		git var GIT_COMMITTER_IDENT >/dev/null || exit
+		echo "Trying really trivial in-index merge..."
+		git-update-index --refresh 2>/dev/null
+		if git-read-tree --trivial -m -u -v $common $head "$1" &&
+		   result_tree=$(git-write-tree)
+		then
+			echo "Wonderful."
+			result_commit=$(
+				echo "$merge_msg" |
+				git-commit-tree $result_tree -p HEAD -p "$1"
+			) || exit
+			finish "$result_commit" "In-index merge"
+			dropsave
+			exit 0
+		fi
+		echo "Nope."
+	esac
 	;;
 *)
 	# An octopus.  If we can reach all the remote we are up to date.
-- 
1.4.4.3.gd2e4
Previous: Shawn O. PearceNext: Junio C Hamano
Message 14 of 17 in “Honor GIT_REFLOG_ACTION in git-rebase.”
  1. 2/11 Honor GIT_REFLOG_ACTION in git-rebase.Shawn O. Pearce, Dec 28, 2006
  2. 3/11 Use branch names in 'git-rebase -m' conflict hunks.Shawn O. Pearce, Dec 28, 2006
  3. 4/11 Ensure `git-pull` fails if `git-merge` fails.Shawn O. Pearce, Dec 28, 2006
  4. 5/11 Honor pull.{twohead,octopus} in git-merge.Shawn O. Pearce, Dec 28, 2006
  5. 6/11 Allow git-merge to select the default strategy.Shawn O. Pearce, Dec 28, 2006
  6. 7/11 Avoid git-fetch in `git-pull .` when possible.Shawn O. Pearce, Dec 28, 2006
  7. Junio C HamanoDec 28, 2006
  8. Shawn PearceDec 28, 2006
  9. Junio C HamanoDec 28, 2006
  10. 8/11 Move better_branch_name above get_ref in merge-recursive.Shawn O. Pearce, Dec 28, 2006
  11. 9/11 Allow merging bare trees in merge-recursive.Shawn O. Pearce, Dec 28, 2006
  12. Junio C HamanoDec 28, 2006
  13. 10/11 Use merge-recursive in git-am -3.Shawn O. Pearce, Dec 28, 2006
  14. 11/11 Improve merge performance by avoiding in-index merges.Shawn O. Pearce, Dec 28, 2006
  15. Junio C HamanoDec 28, 2006
  16. Shawn PearceDec 28, 2006
  17. Johannes SchindelinDec 29, 2006

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.