Skip to content

Commit 0df3245

Browse files
glandiumgitster
authored andcommitted
fast-import: do less work when given "from" matches current branch head
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 unnecessary overhead, and the latter is particularly slow at least on OSX. 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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7ecec52 commit 0df3245

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

fast-import.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2588,14 +2588,12 @@ static int parse_from(struct branch *b)
25882588
{
25892589
const char *from;
25902590
struct branch *s;
2591+
unsigned char sha1[20];
25912592

25922593
if (!skip_prefix(command_buf.buf, "from ", &from))
25932594
return 0;
25942595

2595-
if (b->branch_tree.tree) {
2596-
release_tree_content_recursive(b->branch_tree.tree);
2597-
b->branch_tree.tree = NULL;
2598-
}
2596+
hashcpy(sha1, b->branch_tree.versions[1].sha1);
25992597

26002598
s = lookup_branch(from);
26012599
if (b == s)
@@ -2610,14 +2608,16 @@ static int parse_from(struct branch *b)
26102608
struct object_entry *oe = find_mark(idnum);
26112609
if (oe->type != OBJ_COMMIT)
26122610
die("Mark :%" PRIuMAX " not a commit", idnum);
2613-
hashcpy(b->sha1, oe->idx.sha1);
2614-
if (oe->pack_id != MAX_PACK_ID) {
2615-
unsigned long size;
2616-
char *buf = gfi_unpack_entry(oe, &size);
2617-
parse_from_commit(b, buf, size);
2618-
free(buf);
2619-
} else
2620-
parse_from_existing(b);
2611+
if (hashcmp(b->sha1, oe->idx.sha1)) {
2612+
hashcpy(b->sha1, oe->idx.sha1);
2613+
if (oe->pack_id != MAX_PACK_ID) {
2614+
unsigned long size;
2615+
char *buf = gfi_unpack_entry(oe, &size);
2616+
parse_from_commit(b, buf, size);
2617+
free(buf);
2618+
} else
2619+
parse_from_existing(b);
2620+
}
26212621
} else if (!get_sha1(from, b->sha1)) {
26222622
parse_from_existing(b);
26232623
if (is_null_sha1(b->sha1))
@@ -2626,6 +2626,11 @@ static int parse_from(struct branch *b)
26262626
else
26272627
die("Invalid ref name or SHA1 expression: %s", from);
26282628

2629+
if (b->branch_tree.tree && hashcmp(sha1, b->branch_tree.versions[1].sha1)) {
2630+
release_tree_content_recursive(b->branch_tree.tree);
2631+
b->branch_tree.tree = NULL;
2632+
}
2633+
26292634
read_next_command();
26302635
return 1;
26312636
}

0 commit comments

Comments
 (0)