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

Re: [PATCH 3/2] Optimize the two-way merge of git-read-tree too

From
Linus Torvalds <torvalds@linux-foundation.org>
Date
Aug 10, 2007, 19:53 UTC
Message-ID
<alpine.LFD.0.999.0708101240200.30176@woody.linux-foundation.org>
In-Reply-To
<alpine.LFD.0.999.0708101224110.30176@woody.linux-foundation.org>
On Fri, 10 Aug 2007, Linus Torvalds wrote:
> 
> This trivially optimizes the two-way merge case of git-read-tree too, 
> which affects switching branches.

Side note, if this wasn't obvious: this series of three patches (four, if you count the one in this email) obviates the need for Junio's hacky fix from yesterday that removed the "-i -m" flags from "git read-tree" in git-commit.sh, and made builtin-read-tree sometimes use the "read_tree()" function.

Now "unpack_trees()" is just fast enough that we don't need to avoid it (although it's probably still a good idea to eventually convert it to use the traverse_trees() infrastructure some day - just to avoid having extraneous tree traversal functions).

And as mentioned, the three-way case *should* be as trivial as the following. It passes all the tests, and I verified that a conflicting merge in the 100,000 file horror-case merged correctly (with the conflict markers) in 0.687 seconds with this, so it works, but I'm lazy and somebody else should double-check it.

(Again - *without* this patch, the merge took 8.355 seconds, so this patch really does make a huge difference for merge performance with lots and lots of files, and we're not talking percentages, we're talking orders-of-magnitude differences!)

		Linus
---
 unpack-trees.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/unpack-trees.c b/unpack-trees.c
index 810816e..ccfeb6e 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -667,7 +667,6 @@ int threeway_merge(struct cache_entry **stages,
 	int no_anc_exists = 1;
 	int i;
 
-	remove_entry(remove);		
 	for (i = 1; i < o->head_idx; i++) {
 		if (!stages[i] || stages[i] == o->df_conflict_entry)
 			any_anc_missing = 1;
@@ -730,8 +729,10 @@ int threeway_merge(struct cache_entry **stages,
 	}
 
 	/* #1 */
-	if (!head && !remote && any_anc_missing)
+	if (!head && !remote && any_anc_missing) {
+		remove_entry(remove);
 		return 0;
+	}
 
 	/* Under the new "aggressive" rule, we resolve mostly trivial
 	 * cases that we historically had git-merge-one-file resolve.
@@ -763,6 +764,7 @@ int threeway_merge(struct cache_entry **stages,
 		if ((head_deleted && remote_deleted) ||
 		    (head_deleted && remote && remote_match) ||
 		    (remote_deleted && head && head_match)) {
+			remove_entry(remove);
 			if (index)
 				return deleted_entry(index, index, o);
 			else if (ce && !head_deleted)
@@ -785,6 +787,7 @@ int threeway_merge(struct cache_entry **stages,
 		verify_uptodate(index, o);
 	}
 
+	remove_entry(remove);
 	o->nontrivial_merge = 1;
 
 	/* #2, #3, #4, #6, #7, #9, #10, #11. */
Previous: Linus TorvaldsNext: Junio C Hamano
Message 4 of 7 in “Move old index entry removal from "unpack_trees()" into the individual functions”
  1. 1/2 Move old index entry removal from "unpack_trees()" into the individual functionsLinus Torvalds, Aug 10, 2007
  2. 2/2 Optimize the common cases of git-read-treeLinus Torvalds, Aug 10, 2007
  3. 3/2 Optimize the two-way merge of git-read-tree tooLinus Torvalds, Aug 10, 2007
  4. Linus TorvaldsAug 10, 2007
  5. Junio C HamanoAug 11, 2007
  6. Junio C HamanoAug 11, 2007
  7. Linus TorvaldsAug 11, 2007

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.