diff options
Diffstat (limited to 'send-pack.c')
-rw-r--r-- | send-pack.c | 125 |
1 files changed, 60 insertions, 65 deletions
diff --git a/send-pack.c b/send-pack.c index d2d2a49a02..7b9829f165 100644 --- a/send-pack.c +++ b/send-pack.c @@ -1,6 +1,8 @@ #include "builtin.h" +#include "config.h" #include "commit.h" #include "refs.h" +#include "object-store.h" #include "pkt-line.h" #include "sideband.h" #include "run-command.h" @@ -36,56 +38,46 @@ int option_parse_push_signed(const struct option *opt, die("bad %s argument: %s", opt->long_name, arg); } -static void feed_object(const unsigned char *sha1, FILE *fh, int negative) +static void feed_object(const struct object_id *oid, FILE *fh, int negative) { - if (negative && !has_sha1_file(sha1)) + if (negative && !has_sha1_file(oid->hash)) return; if (negative) putc('^', fh); - fputs(sha1_to_hex(sha1), fh); + fputs(oid_to_hex(oid), fh); putc('\n', fh); } /* * Make a pack stream and spit it out into file descriptor fd */ -static int pack_objects(int fd, struct ref *refs, struct sha1_array *extra, struct send_pack_args *args) +static int pack_objects(int fd, struct ref *refs, struct oid_array *extra, struct send_pack_args *args) { /* * The child becomes pack-objects --revs; we feed * the revision parameters to it via its stdin and * let its stdout go back to the other end. */ - const char *argv[] = { - "pack-objects", - "--all-progress-implied", - "--revs", - "--stdout", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - }; struct child_process po = CHILD_PROCESS_INIT; FILE *po_in; int i; int rc; - i = 4; + argv_array_push(&po.args, "pack-objects"); + argv_array_push(&po.args, "--all-progress-implied"); + argv_array_push(&po.args, "--revs"); + argv_array_push(&po.args, "--stdout"); if (args->use_thin_pack) - argv[i++] = "--thin"; + argv_array_push(&po.args, "--thin"); if (args->use_ofs_delta) - argv[i++] = "--delta-base-offset"; + argv_array_push(&po.args, "--delta-base-offset"); if (args->quiet || !args->progress) - argv[i++] = "-q"; + argv_array_push(&po.args, "-q"); if (args->progress) - argv[i++] = "--progress"; - if (is_repository_shallow()) - argv[i++] = "--shallow"; - po.argv = argv; + argv_array_push(&po.args, "--progress"); + if (is_repository_shallow(the_repository)) + argv_array_push(&po.args, "--shallow"); po.in = -1; po.out = args->stateless_rpc ? -1 : fd; po.git_cmd = 1; @@ -98,13 +90,13 @@ static int pack_objects(int fd, struct ref *refs, struct sha1_array *extra, stru */ po_in = xfdopen(po.in, "w"); for (i = 0; i < extra->nr; i++) - feed_object(extra->sha1[i], po_in, 1); + feed_object(&extra->oid[i], po_in, 1); while (refs) { if (!is_null_oid(&refs->old_oid)) - feed_object(refs->old_oid.hash, po_in, 1); + feed_object(&refs->old_oid, po_in, 1); if (!is_null_oid(&refs->new_oid)) - feed_object(refs->new_oid.hash, po_in, 0); + feed_object(&refs->new_oid, po_in, 0); refs = refs->next; } @@ -132,7 +124,7 @@ static int pack_objects(int fd, struct ref *refs, struct sha1_array *extra, stru * For a normal non-zero exit, we assume pack-objects wrote * something useful to stderr. For death by signal, though, * we should mention it to the user. The exception is SIGPIPE - * (141), because that's a normal occurence if the remote end + * (141), because that's a normal occurrence if the remote end * hangs up (and we'll report that by trying to read the unpack * status). */ @@ -143,36 +135,36 @@ static int pack_objects(int fd, struct ref *refs, struct sha1_array *extra, stru return 0; } -static int receive_unpack_status(int in) +static int receive_unpack_status(struct packet_reader *reader) { - const char *line = packet_read_line(in, NULL); - if (!skip_prefix(line, "unpack ", &line)) - return error(_("unable to parse remote unpack status: %s"), line); - if (strcmp(line, "ok")) - return error(_("remote unpack failed: %s"), line); + if (packet_reader_read(reader) != PACKET_READ_NORMAL) + return error(_("unexpected flush packet while reading remote unpack status")); + if (!skip_prefix(reader->line, "unpack ", &reader->line)) + return error(_("unable to parse remote unpack status: %s"), reader->line); + if (strcmp(reader->line, "ok")) + return error(_("remote unpack failed: %s"), reader->line); return 0; } -static int receive_status(int in, struct ref *refs) +static int receive_status(struct packet_reader *reader, struct ref *refs) { struct ref *hint; int ret; hint = NULL; - ret = receive_unpack_status(in); + ret = receive_unpack_status(reader); while (1) { - char *refname; + const char *refname; char *msg; - char *line = packet_read_line(in, NULL); - if (!line) + if (packet_reader_read(reader) != PACKET_READ_NORMAL) break; - if (!starts_with(line, "ok ") && !starts_with(line, "ng ")) { - error("invalid ref status from remote: %s", line); + if (!starts_with(reader->line, "ok ") && !starts_with(reader->line, "ng ")) { + error("invalid ref status from remote: %s", reader->line); ret = -1; break; } - refname = line + 3; + refname = reader->line + 3; msg = strchr(refname, ' '); if (msg) *msg++ = '\0'; @@ -193,7 +185,7 @@ static int receive_status(int in, struct ref *refs) continue; } - if (line[0] == 'o' && line[1] == 'k') + if (reader->line[0] == 'o' && reader->line[1] == 'k') hint->status = REF_STATUS_OK; else { hint->status = REF_STATUS_REMOTE_REJECT; @@ -209,9 +201,8 @@ static int receive_status(int in, struct ref *refs) static int sideband_demux(int in, int out, void *data) { int *fd = data, ret; -#ifdef NO_PTHREADS - close(fd[1]); -#endif + if (async_with_fork()) + close(fd[1]); ret = recv_sideband("send-pack", fd[0], out); close(out); return ret; @@ -227,7 +218,7 @@ static int advertise_shallow_grafts_cb(const struct commit_graft *graft, void *c static void advertise_shallow_grafts_buf(struct strbuf *sb) { - if (!is_repository_shallow()) + if (!is_repository_shallow(the_repository)) return; for_each_commit_graft(advertise_shallow_grafts_cb, sb); } @@ -376,7 +367,7 @@ static void reject_invalid_nonce(const char *nonce, int len) int send_pack(struct send_pack_args *args, int fd[], struct child_process *conn, struct ref *remote_refs, - struct sha1_array *extra_have) + struct oid_array *extra_have) { int in = fd[0]; int out = fd[1]; @@ -397,6 +388,7 @@ int send_pack(struct send_pack_args *args, int ret; struct async demux; const char *push_cert_nonce = NULL; + struct packet_reader reader; /* Does the other end support the reporting? */ if (server_supports("report-status")) @@ -491,9 +483,12 @@ int send_pack(struct send_pack_args *args, * we were to send it and we're trying to send the refs * atomically, abort the whole operation. */ - if (use_atomic) + if (use_atomic) { + strbuf_release(&req_buf); + strbuf_release(&cap_buf); return atomic_push_failure(args, remote_refs, ref); - /* Fallthrough for non atomic case. */ + } + /* else fallthrough */ default: continue; } @@ -532,8 +527,16 @@ int send_pack(struct send_pack_args *args, } } + if (use_push_options) { + struct string_list_item *item; + + packet_buf_flush(&req_buf); + for_each_string_list_item(item, args->push_options) + packet_buf_write(&req_buf, "%s", item->string); + } + if (args->stateless_rpc) { - if (!args->dry_run && (cmds_sent || is_repository_shallow())) { + if (!args->dry_run && (cmds_sent || is_repository_shallow(the_repository))) { packet_buf_flush(&req_buf); send_sideband(out, -1, req_buf.buf, req_buf.len, LARGE_PACKET_MAX); } @@ -544,18 +547,6 @@ int send_pack(struct send_pack_args *args, strbuf_release(&req_buf); strbuf_release(&cap_buf); - if (use_push_options) { - struct string_list_item *item; - struct strbuf sb = STRBUF_INIT; - - for_each_string_list_item(item, args->push_options) - packet_buf_write(&sb, "%s", item->string); - - write_or_die(out, sb.buf, sb.len); - packet_flush(out); - strbuf_release(&sb); - } - if (use_sideband && cmds_sent) { memset(&demux, 0, sizeof(demux)); demux.proc = sideband_demux; @@ -567,6 +558,10 @@ int send_pack(struct send_pack_args *args, in = demux.out; } + packet_reader_init(&reader, in, NULL, 0, + PACKET_READ_CHOMP_NEWLINE | + PACKET_READ_DIE_ON_ERR_PACKET); + if (need_pack_data && cmds_sent) { if (pack_objects(out, remote_refs, extra_have, args) < 0) { for (ref = remote_refs; ref; ref = ref->next) @@ -581,7 +576,7 @@ int send_pack(struct send_pack_args *args, * are failing, and just want the error() side effects. */ if (status_report) - receive_unpack_status(in); + receive_unpack_status(&reader); if (use_sideband) { close(demux.out); @@ -598,7 +593,7 @@ int send_pack(struct send_pack_args *args, packet_flush(out); if (status_report && cmds_sent) - ret = receive_status(in, remote_refs); + ret = receive_status(&reader, remote_refs); else ret = 0; if (args->stateless_rpc) |