transport-helper: clarify *:* refspec
[gitweb.git] / transport-helper.c
index 4713b6930248d961824c9f867b10340e6278132f..018513baa05fbf199b1c7d8ab5b1e1d41339aec3 100644 (file)
@@ -46,7 +46,7 @@ static void sendline(struct helper_data *helper, struct strbuf *buffer)
                die_errno("Full write to remote helper failed");
 }
 
-static int recvline_fh(FILE *helper, struct strbuf *buffer)
+static int recvline_fh(FILE *helper, struct strbuf *buffer, const char *name)
 {
        strbuf_reset(buffer);
        if (debug)
@@ -54,7 +54,7 @@ static int recvline_fh(FILE *helper, struct strbuf *buffer)
        if (strbuf_getline(buffer, helper, '\n') == EOF) {
                if (debug)
                        fprintf(stderr, "Debug: Remote helper quit.\n");
-               exit(128);
+               die("Reading from helper 'git-remote-%s' failed", name);
        }
 
        if (debug)
@@ -64,7 +64,7 @@ static int recvline_fh(FILE *helper, struct strbuf *buffer)
 
 static int recvline(struct helper_data *helper, struct strbuf *buffer)
 {
-       return recvline_fh(helper->out, buffer);
+       return recvline_fh(helper->out, buffer, helper->name);
 }
 
 static void xchgline(struct helper_data *helper, struct strbuf *buffer)
@@ -469,7 +469,7 @@ static int fetch_with_import(struct transport *transport,
         * were fetching.
         *
         * (If no "refspec" capability was specified, for historical
-        * reasons we default to *:*.)
+        * reasons we default to the equivalent of *:*.)
         *
         * Store the result in to_fetch[i].old_sha1.  Callers such
         * as "git fetch" can use the value to write feedback to the
@@ -536,7 +536,7 @@ static int process_connect_service(struct transport *transport,
                goto exit;
 
        sendline(data, &cmdbuf);
-       recvline_fh(input, &cmdbuf);
+       recvline_fh(input, &cmdbuf, name);
        if (!strcmp(cmdbuf.buf, "")) {
                data->no_disconnect_req = 1;
                if (debug)
@@ -661,6 +661,21 @@ static void push_update_ref_status(struct strbuf *buf,
                        free(msg);
                        msg = NULL;
                }
+               else if (!strcmp(msg, "already exists")) {
+                       status = REF_STATUS_REJECT_ALREADY_EXISTS;
+                       free(msg);
+                       msg = NULL;
+               }
+               else if (!strcmp(msg, "fetch first")) {
+                       status = REF_STATUS_REJECT_FETCH_FIRST;
+                       free(msg);
+                       msg = NULL;
+               }
+               else if (!strcmp(msg, "needs force")) {
+                       status = REF_STATUS_REJECT_NEEDS_FORCE;
+                       free(msg);
+                       msg = NULL;
+               }
        }
 
        if (*ref)
@@ -720,6 +735,7 @@ static int push_refs_with_push(struct transport *transport,
                /* Check for statuses set by set_ref_status_for_push() */
                switch (ref->status) {
                case REF_STATUS_REJECT_NONFASTFORWARD:
+               case REF_STATUS_REJECT_ALREADY_EXISTS:
                case REF_STATUS_UPTODATE:
                        continue;
                default:
@@ -785,6 +801,7 @@ static int push_refs_with_export(struct transport *transport,
                if (private && !get_sha1(private, sha1)) {
                        strbuf_addf(&buf, "^%s", private);
                        string_list_append(&revlist_args, strbuf_detach(&buf, NULL));
+                       hashcpy(ref->old_sha1, sha1);
                }
                free(private);