diff options
Diffstat (limited to 'send-pack.c')
-rw-r--r-- | send-pack.c | 106 |
1 files changed, 45 insertions, 61 deletions
diff --git a/send-pack.c b/send-pack.c index 8d9190f5e7..d1b7edc995 100644 --- a/send-pack.c +++ b/send-pack.c @@ -2,6 +2,7 @@ #include "config.h" #include "commit.h" #include "refs.h" +#include "object-store.h" #include "pkt-line.h" #include "sideband.h" #include "run-command.h" @@ -11,7 +12,7 @@ #include "quote.h" #include "transport.h" #include "version.h" -#include "sha1-array.h" +#include "oid-array.h" #include "gpg-interface.h" #include "cache.h" @@ -37,14 +38,17 @@ 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_object_file_with_flags(oid, + OBJECT_INFO_SKIP_FETCH_OBJECT | + OBJECT_INFO_QUICK)) return; if (negative) putc('^', fh); - fputs(sha1_to_hex(sha1), fh); + fputs(oid_to_hex(oid), fh); putc('\n', fh); } @@ -75,7 +79,7 @@ static int pack_objects(int fd, struct ref *refs, struct oid_array *extra, struc argv_array_push(&po.args, "-q"); if (args->progress) argv_array_push(&po.args, "--progress"); - if (is_repository_shallow()) + if (is_repository_shallow(the_repository)) argv_array_push(&po.args, "--shallow"); po.in = -1; po.out = args->stateless_rpc ? -1 : fd; @@ -89,13 +93,13 @@ static int pack_objects(int fd, struct ref *refs, struct oid_array *extra, struc */ po_in = xfdopen(po.in, "w"); for (i = 0; i < extra->nr; i++) - feed_object(extra->oid[i].hash, 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; } @@ -134,38 +138,36 @@ static int pack_objects(int fd, struct ref *refs, struct oid_array *extra, struc 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 (!line) + if (packet_reader_read(reader) != PACKET_READ_NORMAL) return error(_("unexpected flush packet while reading remote unpack status")); - 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 (!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'; @@ -186,12 +188,10 @@ 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 { + else hint->status = REF_STATUS_REMOTE_REJECT; - ret = -1; - } hint->remote_status = xstrdup_or_null(msg); /* start our next search from the next ref */ hint = hint->next; @@ -202,9 +202,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; @@ -220,7 +219,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); } @@ -321,29 +320,6 @@ free_return: return update_seen; } - -static int atomic_push_failure(struct send_pack_args *args, - struct ref *remote_refs, - struct ref *failing_ref) -{ - struct ref *ref; - /* Mark other refs as failed */ - for (ref = remote_refs; ref; ref = ref->next) { - if (!ref->peer_ref && !args->send_mirror) - continue; - - switch (ref->status) { - case REF_STATUS_EXPECTING_REPORT: - ref->status = REF_STATUS_ATOMIC_PUSH_FAILED; - continue; - default: - break; /* do nothing */ - } - } - return error("atomic push failed for ref %s. status: %d\n", - failing_ref->name, failing_ref->status); -} - #define NONCE_LEN_LIMIT 256 static void reject_invalid_nonce(const char *nonce, int len) @@ -390,6 +366,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")) @@ -487,7 +464,10 @@ int send_pack(struct send_pack_args *args, if (use_atomic) { strbuf_release(&req_buf); strbuf_release(&cap_buf); - return atomic_push_failure(args, remote_refs, ref); + reject_atomic_push(remote_refs, args->send_mirror); + error("atomic push failed for ref %s. status: %d\n", + ref->name, ref->status); + return args->porcelain ? 0 : -1; } /* else fallthrough */ default: @@ -537,7 +517,7 @@ int send_pack(struct send_pack_args *args, } 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); } @@ -559,10 +539,12 @@ 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) - ref->status = REF_STATUS_NONE; if (args->stateless_rpc) close(out); if (git_connection_is_socket(conn)) @@ -570,10 +552,12 @@ int send_pack(struct send_pack_args *args, /* * Do not even bother with the return value; we know we - * are failing, and just want the error() side effects. + * are failing, and just want the error() side effects, + * as well as marking refs with their remote status (if + * we get one). */ if (status_report) - receive_unpack_status(in); + receive_status(&reader, remote_refs); if (use_sideband) { close(demux.out); @@ -590,7 +574,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) |