svn: initial "master" points to trunk if possible
[gitweb.git] / transport.c
index b07406745ebb303b17baae6ba673897359ed7d87..faee154c383c9726017f1995121b510f770b655e 100644 (file)
@@ -158,7 +158,7 @@ static struct ref *get_refs_via_rsync(struct transport *transport, int for_push)
 
        strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
        if (!mkdtemp(temp_dir.buf))
-               die ("Could not make temporary directory");
+               die_errno ("Could not make temporary directory");
        temp_dir_len = temp_dir.len;
 
        strbuf_addstr(&buf, rsync_url(transport->url));
@@ -321,7 +321,7 @@ static int rsync_transport_push(struct transport *transport,
 
        strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
        if (!mkdtemp(temp_dir.buf))
-               die ("Could not make temporary directory");
+               die_errno ("Could not make temporary directory");
        strbuf_addch(&temp_dir, '/');
 
        if (flags & TRANSPORT_PUSH_ALL) {
@@ -396,7 +396,6 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons
 {
        const char **argv;
        int argc;
-       int err;
 
        if (flags & TRANSPORT_PUSH_MIRROR)
                return error("http transport does not support mirror mode");
@@ -416,20 +415,7 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons
        while (refspec_nr--)
                argv[argc++] = *refspec++;
        argv[argc] = NULL;
-       err = run_command_v_opt(argv, RUN_GIT_CMD);
-       switch (err) {
-       case -ERR_RUN_COMMAND_FORK:
-               error("unable to fork for %s", argv[0]);
-       case -ERR_RUN_COMMAND_EXEC:
-               error("unable to exec %s", argv[0]);
-               break;
-       case -ERR_RUN_COMMAND_WAITPID:
-       case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
-       case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
-       case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
-               error("%s died with strange error", argv[0]);
-       }
-       return !!err;
+       return !!run_command_v_opt(argv, RUN_GIT_CMD);
 }
 
 static struct ref *get_refs_via_curl(struct transport *transport, int for_push)
@@ -681,6 +667,21 @@ static int fetch_refs_via_pack(struct transport *transport,
        return (refs ? 0 : -1);
 }
 
+static int push_had_errors(struct ref *ref)
+{
+       for (; ref; ref = ref->next) {
+               switch (ref->status) {
+               case REF_STATUS_NONE:
+               case REF_STATUS_UPTODATE:
+               case REF_STATUS_OK:
+                       break;
+               default:
+                       return 1;
+               }
+       }
+       return 0;
+}
+
 static int refs_pushed(struct ref *ref)
 {
        for (; ref; ref = ref->next) {
@@ -820,7 +821,7 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count, i
 }
 
 static void print_push_status(const char *dest, struct ref *refs,
-                                                         int verbose, int porcelain)
+                             int verbose, int porcelain, int * nonfastforward)
 {
        struct ref *ref;
        int n = 0;
@@ -835,11 +836,14 @@ static void print_push_status(const char *dest, struct ref *refs,
                if (ref->status == REF_STATUS_OK)
                        n += print_one_push_status(ref, dest, n, porcelain);
 
+       *nonfastforward = 0;
        for (ref = refs; ref; ref = ref->next) {
                if (ref->status != REF_STATUS_NONE &&
                    ref->status != REF_STATUS_UPTODATE &&
                    ref->status != REF_STATUS_OK)
                        n += print_one_push_status(ref, dest, n, porcelain);
+               if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD)
+                       *nonfastforward = 1;
        }
 }
 
@@ -892,6 +896,7 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re
        args.force_update = !!(flags & TRANSPORT_PUSH_FORCE);
        args.use_thin_pack = data->thin;
        args.verbose = !!(flags & TRANSPORT_PUSH_VERBOSE);
+       args.quiet = !!(flags & TRANSPORT_PUSH_QUIET);
        args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
 
        ret = send_pack(&args, data->fd, data->conn, remote_refs,
@@ -997,7 +1002,8 @@ int transport_set_option(struct transport *transport,
 }
 
 int transport_push(struct transport *transport,
-                  int refspec_nr, const char **refspec, int flags)
+                  int refspec_nr, const char **refspec, int flags,
+                  int * nonfastforward)
 {
        verify_remote_names(refspec_nr, refspec);
 
@@ -1009,6 +1015,7 @@ int transport_push(struct transport *transport,
                struct ref *local_refs = get_local_heads();
                int match_flags = MATCH_REFS_NONE;
                int verbose = flags & TRANSPORT_PUSH_VERBOSE;
+               int quiet = flags & TRANSPORT_PUSH_QUIET;
                int porcelain = flags & TRANSPORT_PUSH_PORCELAIN;
                int ret;
 
@@ -1024,7 +1031,10 @@ int transport_push(struct transport *transport,
 
                ret = transport->push_refs(transport, remote_refs, flags);
 
-               print_push_status(transport->url, remote_refs, verbose | porcelain, porcelain);
+               if (!quiet || push_had_errors(remote_refs))
+                       print_push_status(transport->url, remote_refs,
+                                       verbose | porcelain, porcelain,
+                                       nonfastforward);
 
                if (!(flags & TRANSPORT_PUSH_DRY_RUN)) {
                        struct ref *ref;