Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 1 | /* |
| 2 | * "git push" |
| 3 | */ |
| 4 | #include "cache.h" |
| 5 | #include "refs.h" |
| 6 | #include "run-command.h" |
| 7 | #include "builtin.h" |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 8 | #include "remote.h" |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 9 | |
Uwe Kleine-König | d23842f | 2007-01-19 13:49:27 +0100 | [diff] [blame] | 10 | static const char push_usage[] = "git-push [--all] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]"; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 11 | |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 12 | static int all, force, thin = 1, verbose; |
Uwe Kleine-König | d23842f | 2007-01-19 13:49:27 +0100 | [diff] [blame] | 13 | static const char *receivepack; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 14 | |
David Rientjes | 96f1e58 | 2006-08-15 10:23:48 -0700 | [diff] [blame] | 15 | static const char **refspec; |
| 16 | static int refspec_nr; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 17 | |
| 18 | static void add_refspec(const char *ref) |
| 19 | { |
| 20 | int nr = refspec_nr + 1; |
| 21 | refspec = xrealloc(refspec, nr * sizeof(char *)); |
| 22 | refspec[nr-1] = ref; |
| 23 | refspec_nr = nr; |
| 24 | } |
| 25 | |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 26 | static void set_refspecs(const char **refs, int nr) |
| 27 | { |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 28 | int i; |
| 29 | for (i = 0; i < nr; i++) { |
| 30 | const char *ref = refs[i]; |
| 31 | if (!strcmp("tag", ref)) { |
| 32 | char *tag; |
| 33 | int len; |
| 34 | if (nr <= ++i) |
| 35 | die("tag shorthand without <tag>"); |
| 36 | len = strlen(refs[i]) + 11; |
| 37 | tag = xmalloc(len); |
| 38 | strcpy(tag, "refs/tags/"); |
| 39 | strcat(tag, refs[i]); |
| 40 | ref = tag; |
Junio C Hamano | 411fb8b | 2006-12-13 10:03:39 -0800 | [diff] [blame] | 41 | } |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 42 | add_refspec(ref); |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 43 | } |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 44 | } |
| 45 | |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 46 | static int do_push(const char *repo) |
| 47 | { |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 48 | int i, errs; |
Nick Hengeveld | 441c823 | 2006-06-05 13:02:29 -0700 | [diff] [blame] | 49 | int common_argc; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 50 | const char **argv; |
| 51 | int argc; |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 52 | struct remote *remote = remote_get(repo); |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 53 | |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 54 | if (!remote) |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 55 | die("bad repository '%s'", repo); |
| 56 | |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 57 | if (remote->receivepack) { |
| 58 | char *rp = xmalloc(strlen(remote->receivepack) + 16); |
| 59 | sprintf(rp, "--receive-pack=%s", remote->receivepack); |
| 60 | receivepack = rp; |
| 61 | } |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 62 | if (!refspec && !all && remote->push_refspec_nr) { |
| 63 | refspec = remote->push_refspec; |
| 64 | refspec_nr = remote->push_refspec_nr; |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 65 | } |
| 66 | |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 67 | argv = xmalloc((refspec_nr + 10) * sizeof(char *)); |
| 68 | argv[0] = "dummy-send-pack"; |
| 69 | argc = 1; |
| 70 | if (all) |
| 71 | argv[argc++] = "--all"; |
| 72 | if (force) |
| 73 | argv[argc++] = "--force"; |
Uwe Kleine-König | d23842f | 2007-01-19 13:49:27 +0100 | [diff] [blame] | 74 | if (receivepack) |
| 75 | argv[argc++] = receivepack; |
Nick Hengeveld | 441c823 | 2006-06-05 13:02:29 -0700 | [diff] [blame] | 76 | common_argc = argc; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 77 | |
Junio C Hamano | fd1d1b0 | 2007-04-06 23:04:53 -0700 | [diff] [blame] | 78 | errs = 0; |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 79 | for (i = 0; i < remote->uri_nr; i++) { |
Pierre Habouzit | 60b7f38 | 2006-08-23 12:39:10 +0200 | [diff] [blame] | 80 | int err; |
Nick Hengeveld | 441c823 | 2006-06-05 13:02:29 -0700 | [diff] [blame] | 81 | int dest_argc = common_argc; |
| 82 | int dest_refspec_nr = refspec_nr; |
| 83 | const char **dest_refspec = refspec; |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 84 | const char *dest = remote->uri[i]; |
Shawn O. Pearce | df91ba3 | 2007-03-12 19:00:15 -0400 | [diff] [blame] | 85 | const char *sender = "send-pack"; |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 86 | if (!prefixcmp(dest, "http://") || |
| 87 | !prefixcmp(dest, "https://")) |
Shawn O. Pearce | df91ba3 | 2007-03-12 19:00:15 -0400 | [diff] [blame] | 88 | sender = "http-push"; |
Daniel Barkalow | b516968 | 2007-05-15 22:50:19 -0400 | [diff] [blame] | 89 | else { |
| 90 | char *rem = xmalloc(strlen(remote->name) + 10); |
| 91 | sprintf(rem, "--remote=%s", remote->name); |
| 92 | argv[dest_argc++] = rem; |
| 93 | if (thin) |
| 94 | argv[dest_argc++] = "--thin"; |
| 95 | } |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 96 | argv[0] = sender; |
Nick Hengeveld | 441c823 | 2006-06-05 13:02:29 -0700 | [diff] [blame] | 97 | argv[dest_argc++] = dest; |
| 98 | while (dest_refspec_nr--) |
| 99 | argv[dest_argc++] = *dest_refspec++; |
| 100 | argv[dest_argc] = NULL; |
Linus Torvalds | bcc785f | 2006-10-30 08:28:59 -0800 | [diff] [blame] | 101 | if (verbose) |
| 102 | fprintf(stderr, "Pushing to %s\n", dest); |
Shawn O. Pearce | df91ba3 | 2007-03-12 19:00:15 -0400 | [diff] [blame] | 103 | err = run_command_v_opt(argv, RUN_GIT_CMD); |
Pierre Habouzit | 60b7f38 | 2006-08-23 12:39:10 +0200 | [diff] [blame] | 104 | if (!err) |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 105 | continue; |
Junio C Hamano | 39878b0 | 2007-04-06 23:04:55 -0700 | [diff] [blame] | 106 | |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 107 | error("failed to push to '%s'", remote->uri[i]); |
Pierre Habouzit | 60b7f38 | 2006-08-23 12:39:10 +0200 | [diff] [blame] | 108 | switch (err) { |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 109 | case -ERR_RUN_COMMAND_FORK: |
Junio C Hamano | fd1d1b0 | 2007-04-06 23:04:53 -0700 | [diff] [blame] | 110 | error("unable to fork for %s", sender); |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 111 | case -ERR_RUN_COMMAND_EXEC: |
Junio C Hamano | fd1d1b0 | 2007-04-06 23:04:53 -0700 | [diff] [blame] | 112 | error("unable to exec %s", sender); |
| 113 | break; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 114 | case -ERR_RUN_COMMAND_WAITPID: |
| 115 | case -ERR_RUN_COMMAND_WAITPID_WRONG_PID: |
| 116 | case -ERR_RUN_COMMAND_WAITPID_SIGNAL: |
| 117 | case -ERR_RUN_COMMAND_WAITPID_NOEXIT: |
Junio C Hamano | fd1d1b0 | 2007-04-06 23:04:53 -0700 | [diff] [blame] | 118 | error("%s died with strange error", sender); |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 119 | } |
Junio C Hamano | fd1d1b0 | 2007-04-06 23:04:53 -0700 | [diff] [blame] | 120 | errs++; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 121 | } |
Junio C Hamano | fd1d1b0 | 2007-04-06 23:04:53 -0700 | [diff] [blame] | 122 | return !!errs; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 123 | } |
| 124 | |
Linus Torvalds | a633fca | 2006-07-28 22:44:25 -0700 | [diff] [blame] | 125 | int cmd_push(int argc, const char **argv, const char *prefix) |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 126 | { |
| 127 | int i; |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 128 | const char *repo = NULL; /* default repository */ |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 129 | |
| 130 | for (i = 1; i < argc; i++) { |
| 131 | const char *arg = argv[i]; |
| 132 | |
| 133 | if (arg[0] != '-') { |
| 134 | repo = arg; |
| 135 | i++; |
| 136 | break; |
| 137 | } |
Linus Torvalds | bcc785f | 2006-10-30 08:28:59 -0800 | [diff] [blame] | 138 | if (!strcmp(arg, "-v")) { |
| 139 | verbose=1; |
| 140 | continue; |
| 141 | } |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 142 | if (!prefixcmp(arg, "--repo=")) { |
Linus Torvalds | bcc785f | 2006-10-30 08:28:59 -0800 | [diff] [blame] | 143 | repo = arg+7; |
| 144 | continue; |
| 145 | } |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 146 | if (!strcmp(arg, "--all")) { |
| 147 | all = 1; |
| 148 | continue; |
| 149 | } |
| 150 | if (!strcmp(arg, "--tags")) { |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 151 | add_refspec("refs/tags/*"); |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 152 | continue; |
| 153 | } |
Jeff King | 8f61549 | 2006-08-02 11:28:16 -0400 | [diff] [blame] | 154 | if (!strcmp(arg, "--force") || !strcmp(arg, "-f")) { |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 155 | force = 1; |
| 156 | continue; |
| 157 | } |
| 158 | if (!strcmp(arg, "--thin")) { |
| 159 | thin = 1; |
| 160 | continue; |
| 161 | } |
| 162 | if (!strcmp(arg, "--no-thin")) { |
| 163 | thin = 0; |
| 164 | continue; |
| 165 | } |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 166 | if (!prefixcmp(arg, "--receive-pack=")) { |
Uwe Kleine-König | d23842f | 2007-01-19 13:49:27 +0100 | [diff] [blame] | 167 | receivepack = arg; |
| 168 | continue; |
| 169 | } |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 170 | if (!prefixcmp(arg, "--exec=")) { |
Uwe Kleine-König | d23842f | 2007-01-19 13:49:27 +0100 | [diff] [blame] | 171 | receivepack = arg; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 172 | continue; |
| 173 | } |
| 174 | usage(push_usage); |
| 175 | } |
| 176 | set_refspecs(argv + i, argc - i); |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 177 | if (all && refspec) |
| 178 | usage(push_usage); |
| 179 | |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 180 | return do_push(repo); |
| 181 | } |