diff options
Diffstat (limited to 'upload-pack.c')
| -rw-r--r-- | upload-pack.c | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/upload-pack.c b/upload-pack.c index c78d55bc67..3a851b3606 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -194,7 +194,13 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data) } struct output_state { - char buffer[8193]; + /* + * We do writes no bigger than LARGE_PACKET_DATA_MAX - 1, because with + * sideband-64k the band designator takes up 1 byte of space. Because + * relay_pack_data keeps the last byte to itself, we make the buffer 1 + * byte bigger than the intended maximum write size. + */ + char buffer[(LARGE_PACKET_DATA_MAX - 1) + 1]; int used; unsigned packfile_uris_started : 1; unsigned packfile_started : 1; @@ -269,7 +275,7 @@ static void create_pack_file(struct upload_pack_data *pack_data, const struct string_list *uri_protocols) { struct child_process pack_objects = CHILD_PROCESS_INIT; - struct output_state output_state = { { 0 } }; + struct output_state *output_state = xcalloc(1, sizeof(struct output_state)); char progress[128]; char abort_msg[] = "aborting due to possible repository " "corruption on the remote side."; @@ -404,7 +410,7 @@ static void create_pack_file(struct upload_pack_data *pack_data, } if (0 <= pu && (pfd[pu].revents & (POLLIN|POLLHUP))) { int result = relay_pack_data(pack_objects.out, - &output_state, + output_state, pack_data->use_sideband, !!uri_protocols); @@ -438,11 +444,12 @@ static void create_pack_file(struct upload_pack_data *pack_data, } /* flush the data */ - if (output_state.used > 0) { - send_client_data(1, output_state.buffer, output_state.used, + if (output_state->used > 0) { + send_client_data(1, output_state->buffer, output_state->used, pack_data->use_sideband); fprintf(stderr, "flushed.\n"); } + free(output_state); if (pack_data->use_sideband) packet_flush(1); return; @@ -596,14 +603,11 @@ static int do_reachable_revlist(struct child_process *cmd, struct object_array *reachable, enum allow_uor allow_uor) { - static const char *argv[] = { - "rev-list", "--stdin", NULL, - }; struct object *o; FILE *cmd_in = NULL; int i; - cmd->argv = argv; + strvec_pushl(&cmd->args, "rev-list", "--stdin", NULL); cmd->git_cmd = 1; cmd->no_stderr = 1; cmd->in = -1; @@ -1396,13 +1400,19 @@ static int parse_want(struct packet_writer *writer, const char *line, const char *arg; if (skip_prefix(line, "want ", &arg)) { struct object_id oid; + struct commit *commit; struct object *o; if (get_oid_hex(arg, &oid)) die("git upload-pack: protocol error, " "expected to get oid, not '%s'", line); - o = parse_object(the_repository, &oid); + commit = lookup_commit_in_graph(the_repository, &oid); + if (commit) + o = &commit->object; + else + o = parse_object(the_repository, &oid); + if (!o) { packet_writer_error(writer, "upload-pack: not our ref %s", @@ -1430,7 +1440,7 @@ static int parse_want_ref(struct packet_writer *writer, const char *line, if (skip_prefix(line, "want-ref ", &refname_nons)) { struct object_id oid; struct string_list_item *item; - struct object *o; + struct object *o = NULL; struct strbuf refname = STRBUF_INIT; strbuf_addf(&refname, "%s%s", get_git_namespace(), refname_nons); @@ -1444,7 +1454,15 @@ static int parse_want_ref(struct packet_writer *writer, const char *line, item = string_list_append(wanted_refs, refname_nons); item->util = oiddup(&oid); - o = parse_object_or_die(&oid, refname_nons); + if (!starts_with(refname_nons, "refs/tags/")) { + struct commit *commit = lookup_commit_in_graph(the_repository, &oid); + if (commit) + o = &commit->object; + } + + if (!o) + o = parse_object_or_die(&oid, refname_nons); + if (!(o->flags & WANTED)) { o->flags |= WANTED; add_object_array(o, NULL, want_obj); |
