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

[PATCH] fast-import: Do less work when given "from" matches current branch head

From
Mike Hommey <mh@glandium.org>
Date
Jul 9, 2015, 06:50 UTC
Message-ID
<1436424609-26159-1-git-send-email-mh@glandium.org>
In-Reply-To
<20150709055227.GA32360@glandium.org>

When building a fast-import stream, it's easy to forget the fact that for non-merge commits happening on top of the current branch head, there is no need for a "from" command. That is corroborated by the fact that at least git-p4, hg-fast-export and felipec's git-remote-hg all unconditionally use a "from" command.

Unfortunately, giving a "from" command always resets the branch tree, forcing it to be re-read, and in many cases, the pack is also closed and reopened through gfi_unpack_entry. Both are extra unwanted overhead, and the latter is particularly slow at least on OSX.

So, avoid resetting the tree when it's unmodified, and avoid calling gfi_unpack_entry when the given mark points to the same commit as the current branch head.

Signed-off-by: Mike Hommey <mh@glandium.org>
---
 fast-import.c | 29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/fast-import.c b/fast-import.c
index e78ca10..372d63a 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -2588,14 +2588,12 @@ static int parse_from(struct branch *b)
 {
 	const char *from;
 	struct branch *s;
+	unsigned char sha1[20];
 
 	if (!skip_prefix(command_buf.buf, "from ", &from))
 		return 0;
 
-	if (b->branch_tree.tree) {
-		release_tree_content_recursive(b->branch_tree.tree);
-		b->branch_tree.tree = NULL;
-	}
+	hashcpy(sha1, b->branch_tree.versions[1].sha1);
 
 	s = lookup_branch(from);
 	if (b == s)
@@ -2610,14 +2608,16 @@ static int parse_from(struct branch *b)
 		struct object_entry *oe = find_mark(idnum);
 		if (oe->type != OBJ_COMMIT)
 			die("Mark :%" PRIuMAX " not a commit", idnum);
-		hashcpy(b->sha1, oe->idx.sha1);
-		if (oe->pack_id != MAX_PACK_ID) {
-			unsigned long size;
-			char *buf = gfi_unpack_entry(oe, &size);
-			parse_from_commit(b, buf, size);
-			free(buf);
-		} else
-			parse_from_existing(b);
+		if (hashcmp(b->sha1, oe->idx.sha1)) {
+			hashcpy(b->sha1, oe->idx.sha1);
+			if (oe->pack_id != MAX_PACK_ID) {
+				unsigned long size;
+				char *buf = gfi_unpack_entry(oe, &size);
+				parse_from_commit(b, buf, size);
+				free(buf);
+			} else
+				parse_from_existing(b);
+		}
 	} else if (!get_sha1(from, b->sha1)) {
 		parse_from_existing(b);
 		if (is_null_sha1(b->sha1))
@@ -2626,6 +2626,11 @@ static int parse_from(struct branch *b)
 	else
 		die("Invalid ref name or SHA1 expression: %s", from);
 
+	if (b->branch_tree.tree && hashcmp(sha1, b->branch_tree.versions[1].sha1)) {
+		release_tree_content_recursive(b->branch_tree.tree);
+		b->branch_tree.tree = NULL;
+	}
+
 	read_next_command();
 	return 1;
 }
-- 
2.4.3.2.gf0a024e.dirty
Previous: Mike HommeyNext: Junio C Hamano
Message 5 of 9 in “suboptimal behavior of fast-import in some cases with "from"”
  1. Mike HommeyJul 6, 2015
  2. Junio C HamanoJul 6, 2015
  3. Mike HommeyJul 9, 2015
  4. Mike HommeyJul 9, 2015
  5. fast-import: Do less work when given "from" matches current branch headMike Hommey, Jul 9, 2015
  6. Junio C HamanoJul 9, 2015
  7. Mike HommeyJul 9, 2015
  8. Junio C HamanoJul 9, 2015
  9. Junio C HamanoJul 9, 2015

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.