diff options
Diffstat (limited to 'builtin/receive-pack.c')
-rw-r--r-- | builtin/receive-pack.c | 64 |
1 files changed, 35 insertions, 29 deletions
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index b618d52139..7020278081 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -21,6 +21,7 @@ #include "sigchain.h" #include "fsck.h" #include "tmp-objdir.h" +#include "oidset.h" static const char * const receive_pack_usage[] = { N_("git receive-pack <git-dir>"), @@ -250,8 +251,9 @@ static void show_ref(const char *path, const unsigned char *sha1) } static int show_ref_cb(const char *path_full, const struct object_id *oid, - int flag, void *unused) + int flag, void *data) { + struct oidset *seen = data; const char *path = strip_namespace(path_full); if (ref_is_hidden(path, path_full)) @@ -260,37 +262,38 @@ static int show_ref_cb(const char *path_full, const struct object_id *oid, /* * Advertise refs outside our current namespace as ".have" * refs, so that the client can use them to minimize data - * transfer but will otherwise ignore them. This happens to - * cover ".have" that are thrown in by add_one_alternate_ref() - * to mark histories that are complete in our alternates as - * well. + * transfer but will otherwise ignore them. */ - if (!path) + if (!path) { + if (oidset_insert(seen, oid)) + return 0; path = ".have"; + } else { + oidset_insert(seen, oid); + } show_ref(path, oid->hash); return 0; } -static int show_one_alternate_sha1(const unsigned char sha1[20], void *unused) +static void show_one_alternate_ref(const char *refname, + const struct object_id *oid, + void *data) { - show_ref(".have", sha1); - return 0; -} + struct oidset *seen = data; -static void collect_one_alternate_ref(const struct ref *ref, void *data) -{ - struct sha1_array *sa = data; - sha1_array_append(sa, ref->old_oid.hash); + if (oidset_insert(seen, oid)) + return; + + show_ref(".have", oid->hash); } static void write_head_info(void) { - struct sha1_array sa = SHA1_ARRAY_INIT; + static struct oidset seen = OIDSET_INIT; - for_each_alternate_ref(collect_one_alternate_ref, &sa); - sha1_array_for_each_unique(&sa, show_one_alternate_sha1, NULL); - sha1_array_clear(&sa); - for_each_ref(show_ref_cb, NULL); + for_each_ref(show_ref_cb, &seen); + for_each_alternate_ref(show_one_alternate_ref, &seen); + oidset_clear(&seen); if (!sent_capabilities) show_ref("capabilities^{}", null_sha1); @@ -1411,7 +1414,7 @@ static void execute_commands(struct command *commands, { struct check_connected_options opt = CHECK_CONNECTED_INIT; struct command *cmd; - unsigned char sha1[20]; + struct object_id oid; struct iterate_data data; struct async muxer; int err_fd = 0; @@ -1468,7 +1471,7 @@ static void execute_commands(struct command *commands, check_aliased_updates(commands); free(head_name_to_free); - head_name = head_name_to_free = resolve_refdup("HEAD", 0, sha1, NULL); + head_name = head_name_to_free = resolve_refdup("HEAD", 0, oid.hash, NULL); if (use_atomic) execute_commands_atomic(commands, si); @@ -1521,7 +1524,7 @@ static void queue_commands_from_cert(struct command **tail, while (boc < eoc) { const char *eol = memchr(boc, '\n', eoc - boc); - tail = queue_command(tail, boc, eol ? eol - boc : eoc - eol); + tail = queue_command(tail, boc, eol ? eol - boc : eoc - boc); boc = eol ? eol + 1 : eoc; } } @@ -1631,12 +1634,17 @@ static const char *parse_pack_header(struct pack_header *hdr) static const char *pack_lockfile; +static void push_header_arg(struct argv_array *args, struct pack_header *hdr) +{ + argv_array_pushf(args, "--pack_header=%"PRIu32",%"PRIu32, + ntohl(hdr->hdr_version), ntohl(hdr->hdr_entries)); +} + static const char *unpack(int err_fd, struct shallow_info *si) { struct pack_header hdr; const char *hdr_err; int status; - char hdr_arg[38]; struct child_process child = CHILD_PROCESS_INIT; int fsck_objects = (receive_fsck_objects >= 0 ? receive_fsck_objects @@ -1650,9 +1658,6 @@ static const char *unpack(int err_fd, struct shallow_info *si) close(err_fd); return hdr_err; } - snprintf(hdr_arg, sizeof(hdr_arg), - "--pack_header=%"PRIu32",%"PRIu32, - ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries)); if (si->nr_ours || si->nr_theirs) { alt_shallow_file = setup_temporary_shallow(si->shallow); @@ -1676,7 +1681,8 @@ static const char *unpack(int err_fd, struct shallow_info *si) tmp_objdir_add_as_alternate(tmp_objdir); if (ntohl(hdr.hdr_entries) < unpack_limit) { - argv_array_pushl(&child.args, "unpack-objects", hdr_arg, NULL); + argv_array_push(&child.args, "unpack-objects"); + push_header_arg(&child.args, &hdr); if (quiet) argv_array_push(&child.args, "-q"); if (fsck_objects) @@ -1694,8 +1700,8 @@ static const char *unpack(int err_fd, struct shallow_info *si) } else { char hostname[256]; - argv_array_pushl(&child.args, "index-pack", - "--stdin", hdr_arg, NULL); + argv_array_pushl(&child.args, "index-pack", "--stdin", NULL); + push_header_arg(&child.args, &hdr); if (gethostname(hostname, sizeof(hostname))) xsnprintf(hostname, sizeof(hostname), "localhost"); |