push: teach --force-with-lease to smart-http transport
[gitweb.git] / remote-curl.c
index 93a09a64c3b1689b0f29a26c6cdd601ef298b975..53c8a3d1a3f24436b6b650a439d36dfaae6547f5 100644 (file)
@@ -6,6 +6,7 @@
 #include "exec_cmd.h"
 #include "run-command.h"
 #include "pkt-line.h"
+#include "string-list.h"
 #include "sideband.h"
 
 static struct remote *remote;
@@ -20,6 +21,7 @@ struct options {
                thin : 1;
 };
 static struct options options;
+static struct string_list cas_options = STRING_LIST_INIT_DUP;
 
 static int set_option(const char *name, const char *value)
 {
@@ -66,6 +68,13 @@ static int set_option(const char *name, const char *value)
                        return -1;
                return 0;
        }
+       else if (!strcmp(name, "cas")) {
+               struct strbuf val = STRBUF_INIT;
+               strbuf_addf(&val, "--" CAS_OPT_NAME "=%s", value);
+               string_list_append(&cas_options, val.buf);
+               strbuf_release(&val);
+               return 0;
+       }
        else {
                return 1 /* unsupported */;
        }
@@ -151,6 +160,33 @@ static void free_discovery(struct discovery *d)
        }
 }
 
+static int show_http_message(struct strbuf *type, struct strbuf *msg)
+{
+       const char *p, *eol;
+
+       /*
+        * We only show text/plain parts, as other types are likely
+        * to be ugly to look at on the user's terminal.
+        *
+        * TODO should handle "; charset=XXX", and re-encode into
+        * logoutputencoding
+        */
+       if (strcasecmp(type->buf, "text/plain"))
+               return -1;
+
+       strbuf_trim(msg);
+       if (!msg->len)
+               return -1;
+
+       p = msg->buf;
+       do {
+               eol = strchrnul(p, '\n');
+               fprintf(stderr, "remote: %.*s\n", (int)(eol - p), p);
+               p = eol + 1;
+       } while(*eol);
+       return 0;
+}
+
 static struct discovery* discover_refs(const char *service, int for_push)
 {
        struct strbuf exp = STRBUF_INIT;
@@ -176,18 +212,20 @@ static struct discovery* discover_refs(const char *service, int for_push)
        }
        refs_url = strbuf_detach(&buffer, NULL);
 
-       http_ret = http_get_strbuf(refs_url, &type, &buffer, HTTP_NO_CACHE);
+       http_ret = http_get_strbuf(refs_url, &type, &buffer,
+                                  HTTP_NO_CACHE | HTTP_KEEP_ERROR);
        switch (http_ret) {
        case HTTP_OK:
                break;
        case HTTP_MISSING_TARGET:
-               die("%s not found: did you run git update-server-info on the"
-                   " server?", refs_url);
+               show_http_message(&type, &buffer);
+               die("repository '%s' not found", url);
        case HTTP_NOAUTH:
-               die("Authentication failed");
+               show_http_message(&type, &buffer);
+               die("Authentication failed for '%s'", url);
        default:
-               http_error(refs_url, http_ret);
-               die("HTTP request failed");
+               show_http_message(&type, &buffer);
+               die("unable to access '%s': %s", url, curl_errorstr);
        }
 
        last= xcalloc(1, sizeof(*last_discovery));
@@ -760,8 +798,9 @@ static int push_git(struct discovery *heads, int nr_spec, char **specs)
        struct rpc_state rpc;
        const char **argv;
        int argc = 0, i, err;
+       struct string_list_item *cas_option;
 
-       argv = xmalloc((10 + nr_spec) * sizeof(char*));
+       argv = xmalloc((10 + nr_spec + cas_options.nr) * sizeof(char *));
        argv[argc++] = "send-pack";
        argv[argc++] = "--stateless-rpc";
        argv[argc++] = "--helper-status";
@@ -774,6 +813,10 @@ static int push_git(struct discovery *heads, int nr_spec, char **specs)
        else if (options.verbosity > 1)
                argv[argc++] = "--verbose";
        argv[argc++] = options.progress ? "--progress" : "--no-progress";
+
+       for_each_string_list_item(cas_option, &cas_options)
+               argv[argc++] = cas_option->string;
+
        argv[argc++] = url;
        for (i = 0; i < nr_spec; i++)
                argv[argc++] = specs[i];