Code

Merge branch 'tr/maint-bundle-boundary' into maint-1.7.8
[git.git] / builtin / send-pack.c
index 2183a470524048eabef1b0f31499c5d04aec5850..cd1115ffc687c642acd4bda09b1ea7976e1e0478 100644 (file)
@@ -1,4 +1,4 @@
-#include "cache.h"
+#include "builtin.h"
 #include "commit.h"
 #include "refs.h"
 #include "pkt-line.h"
@@ -7,6 +7,7 @@
 #include "remote.h"
 #include "send-pack.h"
 #include "quote.h"
+#include "transport.h"
 
 static const char send_pack_usage[] =
 "git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
@@ -47,6 +48,7 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
                NULL,
                NULL,
                NULL,
+               NULL,
        };
        struct child_process po;
        int i;
@@ -58,6 +60,8 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
                argv[i++] = "--delta-base-offset";
        if (args->quiet)
                argv[i++] = "-q";
+       if (args->progress)
+               argv[i++] = "--progress";
        memset(&po, 0, sizeof(po));
        po.argv = argv;
        po.in = -1;
@@ -100,7 +104,7 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
        }
 
        if (finish_command(&po))
-               return error("pack-objects died with strange error");
+               return -1;
        return 0;
 }
 
@@ -169,156 +173,6 @@ static int receive_status(int in, struct ref *refs)
        return ret;
 }
 
-static void update_tracking_ref(struct remote *remote, struct ref *ref)
-{
-       struct refspec rs;
-
-       if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
-               return;
-
-       rs.src = ref->name;
-       rs.dst = NULL;
-
-       if (!remote_find_tracking(remote, &rs)) {
-               if (args.verbose)
-                       fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
-               if (ref->deletion) {
-                       delete_ref(rs.dst, NULL, 0);
-               } else
-                       update_ref("update by push", rs.dst,
-                                       ref->new_sha1, NULL, 0, 0);
-               free(rs.dst);
-       }
-}
-
-#define SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
-
-static void print_ref_status(char flag, const char *summary, struct ref *to, struct ref *from, const char *msg)
-{
-       fprintf(stderr, " %c %-*s ", flag, SUMMARY_WIDTH, summary);
-       if (from)
-               fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name));
-       else
-               fputs(prettify_refname(to->name), stderr);
-       if (msg) {
-               fputs(" (", stderr);
-               fputs(msg, stderr);
-               fputc(')', stderr);
-       }
-       fputc('\n', stderr);
-}
-
-static const char *status_abbrev(unsigned char sha1[20])
-{
-       return find_unique_abbrev(sha1, DEFAULT_ABBREV);
-}
-
-static void print_ok_ref_status(struct ref *ref)
-{
-       if (ref->deletion)
-               print_ref_status('-', "[deleted]", ref, NULL, NULL);
-       else if (is_null_sha1(ref->old_sha1))
-               print_ref_status('*',
-                       (!prefixcmp(ref->name, "refs/tags/") ? "[new tag]" :
-                         "[new branch]"),
-                       ref, ref->peer_ref, NULL);
-       else {
-               char quickref[84];
-               char type;
-               const char *msg;
-
-               strcpy(quickref, status_abbrev(ref->old_sha1));
-               if (ref->nonfastforward) {
-                       strcat(quickref, "...");
-                       type = '+';
-                       msg = "forced update";
-               } else {
-                       strcat(quickref, "..");
-                       type = ' ';
-                       msg = NULL;
-               }
-               strcat(quickref, status_abbrev(ref->new_sha1));
-
-               print_ref_status(type, quickref, ref, ref->peer_ref, msg);
-       }
-}
-
-static int print_one_push_status(struct ref *ref, const char *dest, int count)
-{
-       if (!count)
-               fprintf(stderr, "To %s\n", dest);
-
-       switch(ref->status) {
-       case REF_STATUS_NONE:
-               print_ref_status('X', "[no match]", ref, NULL, NULL);
-               break;
-       case REF_STATUS_REJECT_NODELETE:
-               print_ref_status('!', "[rejected]", ref, NULL,
-                               "remote does not support deleting refs");
-               break;
-       case REF_STATUS_UPTODATE:
-               print_ref_status('=', "[up to date]", ref,
-                               ref->peer_ref, NULL);
-               break;
-       case REF_STATUS_REJECT_NONFASTFORWARD:
-               print_ref_status('!', "[rejected]", ref, ref->peer_ref,
-                               "non-fast-forward");
-               break;
-       case REF_STATUS_REMOTE_REJECT:
-               print_ref_status('!', "[remote rejected]", ref,
-                               ref->deletion ? NULL : ref->peer_ref,
-                               ref->remote_status);
-               break;
-       case REF_STATUS_EXPECTING_REPORT:
-               print_ref_status('!', "[remote failure]", ref,
-                               ref->deletion ? NULL : ref->peer_ref,
-                               "remote failed to report status");
-               break;
-       case REF_STATUS_OK:
-               print_ok_ref_status(ref);
-               break;
-       }
-
-       return 1;
-}
-
-static void print_push_status(const char *dest, struct ref *refs)
-{
-       struct ref *ref;
-       int n = 0;
-
-       if (args.verbose) {
-               for (ref = refs; ref; ref = ref->next)
-                       if (ref->status == REF_STATUS_UPTODATE)
-                               n += print_one_push_status(ref, dest, n);
-       }
-
-       for (ref = refs; ref; ref = ref->next)
-               if (ref->status == REF_STATUS_OK)
-                       n += print_one_push_status(ref, dest, n);
-
-       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);
-       }
-}
-
-static int refs_pushed(struct ref *ref)
-{
-       for (; ref; ref = ref->next) {
-               switch(ref->status) {
-               case REF_STATUS_NONE:
-               case REF_STATUS_UPTODATE:
-                       break;
-               default:
-                       return 1;
-               }
-       }
-       return 0;
-}
-
 static void print_helper_status(struct ref *ref)
 {
        struct strbuf buf = STRBUF_INIT;
@@ -374,8 +228,11 @@ static void print_helper_status(struct ref *ref)
 
 static int sideband_demux(int in, int out, void *data)
 {
-       int *fd = data;
-       int ret = recv_sideband("send-pack", fd[0], out);
+       int *fd = data, ret;
+#ifdef NO_PTHREADS
+       close(fd[1]);
+#endif
+       ret = recv_sideband("send-pack", fd[0], out);
        close(out);
        return ret;
 }
@@ -477,7 +334,7 @@ int send_pack(struct send_pack_args *args,
                demux.data = fd;
                demux.out = -1;
                if (start_async(&demux))
-                       die("receive-pack: unable to fork off sideband demultiplexer");
+                       die("send-pack: unable to fork off sideband demultiplexer");
                in = demux.out;
        }
 
@@ -485,6 +342,10 @@ int send_pack(struct send_pack_args *args,
                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))
+                               shutdown(fd[0], SHUT_WR);
                        if (use_sideband)
                                finish_async(&demux);
                        return -1;
@@ -510,6 +371,10 @@ int send_pack(struct send_pack_args *args,
 
        if (ret < 0)
                return ret;
+
+       if (args->porcelain)
+               return 0;
+
        for (ref = remote_refs; ref; ref = ref->next) {
                switch (ref->status) {
                case REF_STATUS_NONE:
@@ -523,37 +388,6 @@ int send_pack(struct send_pack_args *args,
        return 0;
 }
 
-static void verify_remote_names(int nr_heads, const char **heads)
-{
-       int i;
-
-       for (i = 0; i < nr_heads; i++) {
-               const char *local = heads[i];
-               const char *remote = strrchr(heads[i], ':');
-
-               if (*local == '+')
-                       local++;
-
-               /* A matching refspec is okay.  */
-               if (remote == local && remote[1] == '\0')
-                       continue;
-
-               remote = remote ? (remote + 1) : local;
-               switch (check_ref_format(remote)) {
-               case 0: /* ok */
-               case CHECK_REF_FORMAT_ONELEVEL:
-                       /* ok but a single level -- that is fine for
-                        * a match pattern.
-                        */
-               case CHECK_REF_FORMAT_WILDCARD:
-                       /* ok but ends with a pattern-match character */
-                       continue;
-               }
-               die("remote part of refspec is not a valid name in %s",
-                   heads[i]);
-       }
-}
-
 int cmd_send_pack(int argc, const char **argv, const char *prefix)
 {
        int i, nr_refspecs = 0;
@@ -570,6 +404,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
        int send_all = 0;
        const char *receivepack = "git-receive-pack";
        int flags;
+       int nonfastforward = 0;
 
        argv++;
        for (i = 1; i < argc; i++, argv++) {
@@ -659,10 +494,9 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
 
        memset(&extra_have, 0, sizeof(extra_have));
 
-       get_remote_heads(fd[0], &remote_refs, 0, NULL, REF_NORMAL,
-                        &extra_have);
+       get_remote_heads(fd[0], &remote_refs, REF_NORMAL, &extra_have);
 
-       verify_remote_names(nr_refspecs, refspecs);
+       transport_verify_remote_names(nr_refspecs, refspecs);
 
        local_refs = get_local_heads();
 
@@ -674,7 +508,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
                flags |= MATCH_REFS_MIRROR;
 
        /* match them up */
-       if (match_refs(local_refs, &remote_refs, nr_refspecs, refspecs, flags))
+       if (match_push_refs(local_refs, &remote_refs, nr_refspecs, refspecs, flags))
                return -1;
 
        set_ref_status_for_push(remote_refs, args.send_mirror,
@@ -691,15 +525,15 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
        ret |= finish_connect(conn);
 
        if (!helper_status)
-               print_push_status(dest, remote_refs);
+               transport_print_push_status(dest, remote_refs, args.verbose, 0, &nonfastforward);
 
        if (!args.dry_run && remote) {
                struct ref *ref;
                for (ref = remote_refs; ref; ref = ref->next)
-                       update_tracking_ref(remote, ref);
+                       transport_update_tracking_ref(remote, ref, args.verbose);
        }
 
-       if (!ret && !refs_pushed(remote_refs))
+       if (!ret && !transport_refs_pushed(remote_refs))
                fprintf(stderr, "Everything up-to-date\n");
 
        return ret;