pager: Work around window resizing bug in 'less'
[gitweb.git] / builtin-push.c
index 5f7eccf14b272fc108bcd49aece911ebde460b4f..5f4d7d34d35da35f0c843962f1ca1ae61a575456 100644 (file)
@@ -8,10 +8,10 @@
 
 #define MAX_URI (16)
 
-static const char push_usage[] = "git-push [--all] [--tags] [-f | --force] <repository> [<refspec>...]";
+static const char push_usage[] = "git-push [--all] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]";
 
-static int all, tags, force, thin = 1;
-static const char *execute;
+static int all, tags, force, thin = 1, verbose;
+static const char *receivepack;
 
 #define BUF_SIZE (2084)
 static char buffer[BUF_SIZE];
@@ -57,11 +57,36 @@ static void expand_refspecs(void)
 static void set_refspecs(const char **refs, int nr)
 {
        if (nr) {
-               size_t bytes = nr * sizeof(char *);
-
-               refspec = xrealloc(refspec, bytes);
-               memcpy(refspec, refs, bytes);
-               refspec_nr = nr;
+               int pass;
+               for (pass = 0; pass < 2; pass++) {
+                       /* pass 0 counts and allocates, pass 1 fills */
+                       int i, cnt;
+                       for (i = cnt = 0; i < nr; i++) {
+                               if (!strcmp("tag", refs[i])) {
+                                       int len;
+                                       char *tag;
+                                       if (nr <= ++i)
+                                               die("tag <tag> shorthand without <tag>");
+                                       if (pass) {
+                                               len = strlen(refs[i]) + 11;
+                                               tag = xmalloc(len);
+                                               strcpy(tag, "refs/tags/");
+                                               strcat(tag, refs[i]);
+                                               refspec[cnt] = tag;
+                                       }
+                                       cnt++;
+                                       continue;
+                               }
+                               if (pass)
+                                       refspec[cnt] = refs[i];
+                               cnt++;
+                       }
+                       if (!pass) {
+                               size_t bytes = cnt * sizeof(char *);
+                               refspec_nr = cnt;
+                               refspec = xrealloc(refspec, bytes);
+                       }
+               }
        }
        expand_refspecs();
 }
@@ -118,6 +143,7 @@ static const char *config_repo;
 static int config_repo_len;
 static int config_current_uri;
 static int config_get_refspecs;
+static int config_get_receivepack;
 
 static int get_remote_config(const char* key, const char* value)
 {
@@ -132,6 +158,15 @@ static int get_remote_config(const char* key, const char* value)
                else if (config_get_refspecs &&
                         !strcmp(key + 7 + config_repo_len, ".push"))
                        add_refspec(xstrdup(value));
+               else if (config_get_receivepack &&
+                        !strcmp(key + 7 + config_repo_len, ".receivepack")) {
+                       if (!receivepack) {
+                               char *rp = xmalloc(strlen(value) + 16);
+                               sprintf(rp, "--receive-pack=%s", value);
+                               receivepack = rp;
+                       } else
+                               error("more than one receivepack given, using the first");
+               }
        }
        return 0;
 }
@@ -143,6 +178,7 @@ static int get_config_remotes_uri(const char *repo, const char *uri[MAX_URI])
        config_current_uri = 0;
        config_uri = uri;
        config_get_refspecs = !(refspec_nr || all || tags);
+       config_get_receivepack = (receivepack == NULL);
 
        git_config(get_remote_config);
        return config_current_uri;
@@ -227,8 +263,8 @@ static int do_push(const char *repo)
                argv[argc++] = "--all";
        if (force)
                argv[argc++] = "--force";
-       if (execute)
-               argv[argc++] = execute;
+       if (receivepack)
+               argv[argc++] = receivepack;
        common_argc = argc;
 
        for (i = 0; i < n; i++) {
@@ -248,7 +284,9 @@ static int do_push(const char *repo)
                while (dest_refspec_nr--)
                        argv[dest_argc++] = *dest_refspec++;
                argv[dest_argc] = NULL;
-               err = run_command_v(argc, argv);
+               if (verbose)
+                       fprintf(stderr, "Pushing to %s\n", dest);
+               err = run_command_v(argv);
                if (!err)
                        continue;
                switch (err) {
@@ -281,6 +319,14 @@ int cmd_push(int argc, const char **argv, const char *prefix)
                        i++;
                        break;
                }
+               if (!strcmp(arg, "-v")) {
+                       verbose=1;
+                       continue;
+               }
+               if (!strncmp(arg, "--repo=", 7)) {
+                       repo = arg+7;
+                       continue;
+               }
                if (!strcmp(arg, "--all")) {
                        all = 1;
                        continue;
@@ -301,8 +347,12 @@ int cmd_push(int argc, const char **argv, const char *prefix)
                        thin = 0;
                        continue;
                }
+               if (!strncmp(arg, "--receive-pack=", 15)) {
+                       receivepack = arg;
+                       continue;
+               }
                if (!strncmp(arg, "--exec=", 7)) {
-                       execute = arg;
+                       receivepack = arg;
                        continue;
                }
                usage(push_usage);