summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2015-08-03 11:01:24 -0700
committerJunio C Hamano <gitster@pobox.com>2015-08-03 11:01:24 -0700
commit3ecca8879a07889884dcdc90066c76c4e948856a (patch)
tree9e6e98735ea13af60f756cfc8c18c842c7c1327d
parent85df7cd48739cf252c4e6621251845f8ee117d6a (diff)
parent0df3245721580a3d48c9766a311dd0e3367844b8 (diff)
downloadgit-3ecca8879a07889884dcdc90066c76c4e948856a.tar.gz
Merge branch 'mh/fast-import-optimize-current-from'
Often a fast-import stream builds a new commit on top of the previous commit it built, and it often unconditionally emits a "from" command to specify the first parent, which can be omitted in such a case. This caused fast-import to forget the tree of the previous commit and then re-read it from scratch, which was inefficient. Optimize for this common case. * mh/fast-import-optimize-current-from: fast-import: do less work when given "from" matches current branch head
-rw-r--r--fast-import.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/fast-import.c b/fast-import.c
index 9d949d1f77..6a0c0ac570 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -2594,14 +2594,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)
@@ -2616,14 +2614,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))
@@ -2632,6 +2632,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;
}