diff options
author | Junio C Hamano <gitster@pobox.com> | 2015-08-03 11:01:24 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-08-03 11:01:24 -0700 |
commit | 3ecca8879a07889884dcdc90066c76c4e948856a (patch) | |
tree | 9e6e98735ea13af60f756cfc8c18c842c7c1327d /fast-import.c | |
parent | 85df7cd48739cf252c4e6621251845f8ee117d6a (diff) | |
parent | 0df3245721580a3d48c9766a311dd0e3367844b8 (diff) | |
download | git-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
Diffstat (limited to 'fast-import.c')
-rw-r--r-- | fast-import.c | 29 |
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; } |