From: Junio C Hamano Date: Mon, 3 Aug 2015 18:01:24 +0000 (-0700) Subject: Merge branch 'mh/fast-import-optimize-current-from' X-Git-Tag: v2.6.0-rc0~96 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/3ecca8879a07889884dcdc90066c76c4e948856a?hp=-c 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 --- 3ecca8879a07889884dcdc90066c76c4e948856a diff --combined fast-import.c index 9d949d1f77,ece0096623..6a0c0ac570 --- a/fast-import.c +++ b/fast-import.c @@@ -134,17 -134,16 +134,17 @@@ Format of STDIN stream ts ::= # time since the epoch in seconds, ascii base10 notation; tz ::= # GIT style timezone; - # note: comments, ls and cat requests may appear anywhere - # in the input, except within a data command. Any form - # of the data command always escapes the related input - # from comment processing. + # note: comments, get-mark, ls-tree, and cat-blob requests may + # appear anywhere in the input, except within a data command. Any + # form of the data command always escapes the related input from + # comment processing. # # In case it is not clear, the '#' that starts the comment # must be the first character on that line (an lf # preceded it). # + get_mark ::= 'get-mark' sp idnum lf; cat_blob ::= 'cat-blob' sp (hexsha1 | idnum) lf; ls_tree ::= 'ls' sp (hexsha1 | idnum) sp path_str lf; @@@ -373,7 -372,6 +373,7 @@@ static volatile sig_atomic_t checkpoint static int cat_blob_fd = STDOUT_FILENO; static void parse_argv(void); +static void parse_get_mark(const char *p); static void parse_cat_blob(const char *p); static void parse_ls(const char *p, struct branch *b); @@@ -1694,13 -1692,13 +1694,13 @@@ static int update_branch(struct branch unsigned char old_sha1[20]; struct strbuf err = STRBUF_INIT; - if (read_ref(b->name, old_sha1)) - hashclr(old_sha1); if (is_null_sha1(b->sha1)) { if (b->delete) - delete_ref(b->name, old_sha1, 0); + delete_ref(b->name, NULL, 0); return 0; } + if (read_ref(b->name, old_sha1)) + hashclr(old_sha1); if (!force_update && !is_null_sha1(old_sha1)) { struct commit *old_cmit, *new_cmit; @@@ -1909,10 -1907,6 +1909,10 @@@ static int read_next_command(void rc->prev->next = rc; cmd_tail = rc; } + if (skip_prefix(command_buf.buf, "get-mark ", &p)) { + parse_get_mark(p); + continue; + } if (skip_prefix(command_buf.buf, "cat-blob ", &p)) { parse_cat_blob(p); continue; @@@ -2594,14 -2588,12 +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 -2608,16 +2614,16 @@@ 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 -2626,11 +2632,11 @@@ 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; } @@@ -2925,23 -2924,6 +2930,23 @@@ static void cat_blob(struct object_entr free(buf); } +static void parse_get_mark(const char *p) +{ + struct object_entry *oe = oe; + char output[42]; + + /* get-mark SP LF */ + if (*p != ':') + die("Not a mark: %s", p); + + oe = find_mark(parse_mark_ref_eol(p)); + if (!oe) + die("Unknown mark: %s", command_buf.buf); + + snprintf(output, sizeof(output), "%s\n", sha1_to_hex(oe->idx.sha1)); + cat_blob_write(output, 41); +} + static void parse_cat_blob(const char *p) { struct object_entry *oe = oe; @@@ -3263,8 -3245,6 +3268,8 @@@ static int parse_one_feature(const cha option_import_marks(arg, from_stream, 1); } else if (skip_prefix(feature, "export-marks=", &arg)) { option_export_marks(arg); + } else if (!strcmp(feature, "get-mark")) { + ; /* Don't die - this feature is supported */ } else if (!strcmp(feature, "cat-blob")) { ; /* Don't die - this feature is supported */ } else if (!strcmp(feature, "relative-marks")) {