git-svn: support for funky branch and project names over HTTP(S)
[gitweb.git] / builtin-fetch-pack.c
index 871b7042e74837b5dfd26f17f4317d4341c01100..bb1742f1a267042a00f0a81bca32a4eefe87fd5d 100644 (file)
 static int transfer_unpack_limit = -1;
 static int fetch_unpack_limit = -1;
 static int unpack_limit = 100;
-static struct fetch_pack_args args;
+static struct fetch_pack_args args = {
+       /* .uploadpack = */ "git-upload-pack",
+};
 
 static const char fetch_pack_usage[] =
 "git-fetch-pack [--all] [--quiet|-q] [--keep|-k] [--thin] [--upload-pack=<git-upload-pack>] [--depth=<n>] [--no-progress] [-v] [<host>:]<directory> [<refs>...]";
-static const char *uploadpack = "git-upload-pack";
 
 #define COMPLETE       (1U << 0)
 #define COMMON         (1U << 1)
@@ -31,7 +32,7 @@ static const char *uploadpack = "git-upload-pack";
 #define MAX_IN_VAIN 256
 
 static struct commit_list *rev_list;
-static int non_common_revs, multi_ack, use_thin_pack, use_sideband;
+static int non_common_revs, multi_ack, use_sideband;
 
 static void rev_list_push(struct commit *commit, int mark)
 {
@@ -177,7 +178,7 @@ static int find_common(int fd[2], unsigned char *result_sha1,
                                     (multi_ack ? " multi_ack" : ""),
                                     (use_sideband == 2 ? " side-band-64k" : ""),
                                     (use_sideband == 1 ? " side-band" : ""),
-                                    (use_thin_pack ? " thin-pack" : ""),
+                                    (args.use_thin_pack ? " thin-pack" : ""),
                                     (args.no_progress ? " no-progress" : ""),
                                     " ofs-delta");
                else
@@ -457,42 +458,37 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
        return retval;
 }
 
-static pid_t setup_sideband(int fd[2], int xd[2])
+static int sideband_demux(int fd, void *data)
 {
-       pid_t side_pid;
+       int *xd = data;
 
+       close(xd[1]);
+       return recv_sideband("fetch-pack", xd[0], fd, 2);
+}
+
+static void setup_sideband(int fd[2], int xd[2], struct async *demux)
+{
        if (!use_sideband) {
                fd[0] = xd[0];
                fd[1] = xd[1];
-               return 0;
+               return;
        }
        /* xd[] is talking with upload-pack; subprocess reads from
         * xd[0], spits out band#2 to stderr, and feeds us band#1
-        * through our fd[0].
+        * through demux->out.
         */
-       if (pipe(fd) < 0)
-               die("fetch-pack: unable to set up pipe");
-       side_pid = fork();
-       if (side_pid < 0)
+       demux->proc = sideband_demux;
+       demux->data = xd;
+       if (start_async(demux))
                die("fetch-pack: unable to fork off sideband demultiplexer");
-       if (!side_pid) {
-               /* subprocess */
-               close(fd[0]);
-               if (xd[0] != xd[1])
-                       close(xd[1]);
-               if (recv_sideband("fetch-pack", xd[0], fd[1], 2))
-                       exit(1);
-               exit(0);
-       }
        close(xd[0]);
-       close(fd[1]);
+       fd[0] = demux->out;
        fd[1] = xd[1];
-       return side_pid;
 }
 
 static int get_pack(int xd[2], char **pack_lockfile)
 {
-       pid_t side_pid;
+       struct async demux;
        int fd[2];
        const char *argv[20];
        char keep_arg[256];
@@ -501,7 +497,7 @@ static int get_pack(int xd[2], char **pack_lockfile)
        int do_keep = args.keep_pack;
        struct child_process cmd;
 
-       side_pid = setup_sideband(fd, xd);
+       setup_sideband(fd, xd, &demux);
 
        memset(&cmd, 0, sizeof(cmd));
        cmd.argv = argv;
@@ -556,6 +552,8 @@ static int get_pack(int xd[2], char **pack_lockfile)
 
        if (finish_command(&cmd))
                die("%s failed", argv[0]);
+       if (use_sideband && finish_async(&demux))
+               die("error in sideband demultiplexer");
        return 0;
 }
 
@@ -749,7 +747,7 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
                        st.st_mtime = 0;
        }
 
-       conn = git_connect(fd, (char *)dest, uploadpack,
+       conn = git_connect(fd, (char *)dest, args.uploadpack,
                           args.verbose ? CONNECT_VERBOSE : 0);
        if (heads && nr_heads)
                nr_heads = remove_duplicates(nr_heads, heads);