]> git.ipfire.org Git - thirdparty/git.git/blobdiff - builtin/receive-pack.c
Merge branch 'jx/t5411-flake-fix'
[thirdparty/git.git] / builtin / receive-pack.c
index bb9909c52e4e01e0ab37dbd020138ba254d44b51..f1f0f7bef670d0867c610789c23fd7176e4770b0 100644 (file)
@@ -977,15 +977,25 @@ static int read_proc_receive_report(struct packet_reader *reader,
        int new_report = 0;
        int code = 0;
        int once = 0;
+       int response = 0;
 
        for (;;) {
                struct object_id old_oid, new_oid;
                const char *head;
                const char *refname;
                char *p;
-
-               if (packet_reader_read(reader) != PACKET_READ_NORMAL)
+               enum packet_read_status status;
+
+               status = packet_reader_read(reader);
+               if (status != PACKET_READ_NORMAL) {
+                       /* Check whether proc-receive exited abnormally */
+                       if (status == PACKET_READ_EOF && !response) {
+                               strbuf_addstr(errmsg, "proc-receive exited abnormally");
+                               return -1;
+                       }
                        break;
+               }
+               response++;
 
                head = reader->line;
                p = strchr(head, ' ');
@@ -1145,31 +1155,49 @@ static int run_proc_receive_hook(struct command *commands,
        if (use_push_options)
                strbuf_addstr(&cap, " push-options");
        if (cap.len) {
-               packet_write_fmt(proc.in, "version=1%c%s\n", '\0', cap.buf + 1);
+               code = packet_write_fmt_gently(proc.in, "version=1%c%s\n", '\0', cap.buf + 1);
                strbuf_release(&cap);
        } else {
-               packet_write_fmt(proc.in, "version=1\n");
+               code = packet_write_fmt_gently(proc.in, "version=1\n");
        }
-       packet_flush(proc.in);
+       if (!code)
+               code = packet_flush_gently(proc.in);
 
-       for (;;) {
-               int linelen;
+       if (!code)
+               for (;;) {
+                       int linelen;
+                       enum packet_read_status status;
 
-               if (packet_reader_read(&reader) != PACKET_READ_NORMAL)
-                       break;
+                       status = packet_reader_read(&reader);
+                       if (status != PACKET_READ_NORMAL) {
+                               /* Check whether proc-receive exited abnormally */
+                               if (status == PACKET_READ_EOF)
+                                       code = -1;
+                               break;
+                       }
 
-               if (reader.pktlen > 8 && starts_with(reader.line, "version=")) {
-                       version = atoi(reader.line + 8);
-                       linelen = strlen(reader.line);
-                       if (linelen < reader.pktlen) {
-                               const char *feature_list = reader.line + linelen + 1;
-                               if (parse_feature_request(feature_list, "push-options"))
-                                       hook_use_push_options = 1;
+                       if (reader.pktlen > 8 && starts_with(reader.line, "version=")) {
+                               version = atoi(reader.line + 8);
+                               linelen = strlen(reader.line);
+                               if (linelen < reader.pktlen) {
+                                       const char *feature_list = reader.line + linelen + 1;
+                                       if (parse_feature_request(feature_list, "push-options"))
+                                               hook_use_push_options = 1;
+                               }
                        }
                }
+
+       if (code) {
+               strbuf_addstr(&errmsg, "fail to negotiate version with proc-receive hook");
+               goto cleanup;
        }
 
-       if (version != 1) {
+       switch (version) {
+       case 0:
+               /* fallthrough */
+       case 1:
+               break;
+       default:
                strbuf_addf(&errmsg, "proc-receive version '%d' is not supported",
                            version);
                code = -1;
@@ -1180,20 +1208,36 @@ static int run_proc_receive_hook(struct command *commands,
        for (cmd = commands; cmd; cmd = cmd->next) {
                if (!cmd->run_proc_receive || cmd->skip_update || cmd->error_string)
                        continue;
-               packet_write_fmt(proc.in, "%s %s %s",
-                                oid_to_hex(&cmd->old_oid),
-                                oid_to_hex(&cmd->new_oid),
-                                cmd->ref_name);
+               code = packet_write_fmt_gently(proc.in, "%s %s %s",
+                                              oid_to_hex(&cmd->old_oid),
+                                              oid_to_hex(&cmd->new_oid),
+                                              cmd->ref_name);
+               if (code)
+                       break;
+       }
+       if (!code)
+               code = packet_flush_gently(proc.in);
+       if (code) {
+               strbuf_addstr(&errmsg, "fail to write commands to proc-receive hook");
+               goto cleanup;
        }
-       packet_flush(proc.in);
 
        /* Send push options */
        if (hook_use_push_options) {
                struct string_list_item *item;
 
-               for_each_string_list_item(item, push_options)
-                       packet_write_fmt(proc.in, "%s", item->string);
-               packet_flush(proc.in);
+               for_each_string_list_item(item, push_options) {
+                       code = packet_write_fmt_gently(proc.in, "%s", item->string);
+                       if (code)
+                               break;
+               }
+               if (!code)
+                       code = packet_flush_gently(proc.in);
+               if (code) {
+                       strbuf_addstr(&errmsg,
+                                     "fail to write push-options to proc-receive hook");
+                       goto cleanup;
+               }
        }
 
        /* Read result from proc-receive */