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" |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 9 | #include "transport.h" |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 10 | |
Brian Ewins | 11f2441 | 2007-10-11 20:32:27 +0100 | [diff] [blame] | 11 | static const char push_usage[] = "git-push [--all] [--dry-run] [--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] | 12 | |
Shawn O. Pearce | 18184f7 | 2007-10-16 00:25:34 -0400 | [diff] [blame] | 13 | static int thin, verbose; |
Uwe Kleine-König | d23842f | 2007-01-19 13:49:27 +0100 | [diff] [blame] | 14 | static const char *receivepack; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 15 | |
David Rientjes | 96f1e58 | 2006-08-15 10:23:48 -0700 | [diff] [blame] | 16 | static const char **refspec; |
| 17 | static int refspec_nr; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 18 | |
| 19 | static void add_refspec(const char *ref) |
| 20 | { |
| 21 | int nr = refspec_nr + 1; |
| 22 | refspec = xrealloc(refspec, nr * sizeof(char *)); |
| 23 | refspec[nr-1] = ref; |
| 24 | refspec_nr = nr; |
| 25 | } |
| 26 | |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 27 | static void set_refspecs(const char **refs, int nr) |
| 28 | { |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 29 | int i; |
| 30 | for (i = 0; i < nr; i++) { |
| 31 | const char *ref = refs[i]; |
| 32 | if (!strcmp("tag", ref)) { |
| 33 | char *tag; |
| 34 | int len; |
| 35 | if (nr <= ++i) |
| 36 | die("tag shorthand without <tag>"); |
| 37 | len = strlen(refs[i]) + 11; |
| 38 | tag = xmalloc(len); |
| 39 | strcpy(tag, "refs/tags/"); |
| 40 | strcat(tag, refs[i]); |
| 41 | ref = tag; |
Junio C Hamano | 411fb8b | 2006-12-13 10:03:39 -0800 | [diff] [blame] | 42 | } |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 43 | add_refspec(ref); |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 44 | } |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 45 | } |
| 46 | |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 47 | static int do_push(const char *repo, int flags) |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 48 | { |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 49 | int i, errs; |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 50 | struct remote *remote = remote_get(repo); |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 51 | |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 52 | if (!remote) |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 53 | die("bad repository '%s'", repo); |
| 54 | |
Shawn O. Pearce | 18184f7 | 2007-10-16 00:25:34 -0400 | [diff] [blame] | 55 | if (!refspec |
| 56 | && !(flags & TRANSPORT_PUSH_ALL) |
| 57 | && remote->push_refspec_nr) { |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 58 | refspec = remote->push_refspec; |
| 59 | refspec_nr = remote->push_refspec_nr; |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 60 | } |
Junio C Hamano | fd1d1b0 | 2007-04-06 23:04:53 -0700 | [diff] [blame] | 61 | errs = 0; |
Shawn O. Pearce | 28b91f8 | 2007-09-19 00:49:27 -0400 | [diff] [blame] | 62 | for (i = 0; i < remote->url_nr; i++) { |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 63 | struct transport *transport = |
Shawn O. Pearce | 28b91f8 | 2007-09-19 00:49:27 -0400 | [diff] [blame] | 64 | transport_get(remote, remote->url[i]); |
Pierre Habouzit | 60b7f38 | 2006-08-23 12:39:10 +0200 | [diff] [blame] | 65 | int err; |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 66 | if (receivepack) |
| 67 | transport_set_option(transport, |
| 68 | TRANS_OPT_RECEIVEPACK, receivepack); |
| 69 | if (thin) |
| 70 | transport_set_option(transport, TRANS_OPT_THIN, "yes"); |
| 71 | |
Linus Torvalds | bcc785f | 2006-10-30 08:28:59 -0800 | [diff] [blame] | 72 | if (verbose) |
Shawn O. Pearce | 28b91f8 | 2007-09-19 00:49:27 -0400 | [diff] [blame] | 73 | fprintf(stderr, "Pushing to %s\n", remote->url[i]); |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 74 | err = transport_push(transport, refspec_nr, refspec, flags); |
| 75 | err |= transport_disconnect(transport); |
| 76 | |
Pierre Habouzit | 60b7f38 | 2006-08-23 12:39:10 +0200 | [diff] [blame] | 77 | if (!err) |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 78 | continue; |
Junio C Hamano | 39878b0 | 2007-04-06 23:04:55 -0700 | [diff] [blame] | 79 | |
Shawn O. Pearce | 28b91f8 | 2007-09-19 00:49:27 -0400 | [diff] [blame] | 80 | error("failed to push to '%s'", remote->url[i]); |
Junio C Hamano | fd1d1b0 | 2007-04-06 23:04:53 -0700 | [diff] [blame] | 81 | errs++; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 82 | } |
Junio C Hamano | fd1d1b0 | 2007-04-06 23:04:53 -0700 | [diff] [blame] | 83 | return !!errs; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 84 | } |
| 85 | |
Linus Torvalds | a633fca | 2006-07-28 22:44:25 -0700 | [diff] [blame] | 86 | int cmd_push(int argc, const char **argv, const char *prefix) |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 87 | { |
| 88 | int i; |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 89 | int flags = 0; |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 90 | const char *repo = NULL; /* default repository */ |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 91 | |
| 92 | for (i = 1; i < argc; i++) { |
| 93 | const char *arg = argv[i]; |
| 94 | |
| 95 | if (arg[0] != '-') { |
| 96 | repo = arg; |
| 97 | i++; |
| 98 | break; |
| 99 | } |
Linus Torvalds | bcc785f | 2006-10-30 08:28:59 -0800 | [diff] [blame] | 100 | if (!strcmp(arg, "-v")) { |
| 101 | verbose=1; |
| 102 | continue; |
| 103 | } |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 104 | if (!prefixcmp(arg, "--repo=")) { |
Linus Torvalds | bcc785f | 2006-10-30 08:28:59 -0800 | [diff] [blame] | 105 | repo = arg+7; |
| 106 | continue; |
| 107 | } |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 108 | if (!strcmp(arg, "--all")) { |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 109 | flags |= TRANSPORT_PUSH_ALL; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 110 | continue; |
| 111 | } |
Brian Ewins | 11f2441 | 2007-10-11 20:32:27 +0100 | [diff] [blame] | 112 | if (!strcmp(arg, "--dry-run")) { |
Shawn O. Pearce | 2e13e5d | 2007-10-16 00:15:25 -0400 | [diff] [blame] | 113 | flags |= TRANSPORT_PUSH_DRY_RUN; |
Brian Ewins | 11f2441 | 2007-10-11 20:32:27 +0100 | [diff] [blame] | 114 | continue; |
| 115 | } |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 116 | if (!strcmp(arg, "--tags")) { |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 117 | add_refspec("refs/tags/*"); |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 118 | continue; |
| 119 | } |
Jeff King | 8f61549 | 2006-08-02 11:28:16 -0400 | [diff] [blame] | 120 | if (!strcmp(arg, "--force") || !strcmp(arg, "-f")) { |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 121 | flags |= TRANSPORT_PUSH_FORCE; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 122 | continue; |
| 123 | } |
| 124 | if (!strcmp(arg, "--thin")) { |
| 125 | thin = 1; |
| 126 | continue; |
| 127 | } |
| 128 | if (!strcmp(arg, "--no-thin")) { |
| 129 | thin = 0; |
| 130 | continue; |
| 131 | } |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 132 | if (!prefixcmp(arg, "--receive-pack=")) { |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 133 | receivepack = arg + 15; |
Uwe Kleine-König | d23842f | 2007-01-19 13:49:27 +0100 | [diff] [blame] | 134 | continue; |
| 135 | } |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 136 | if (!prefixcmp(arg, "--exec=")) { |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 137 | receivepack = arg + 7; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 138 | continue; |
| 139 | } |
| 140 | usage(push_usage); |
| 141 | } |
| 142 | set_refspecs(argv + i, argc - i); |
Shawn O. Pearce | 18184f7 | 2007-10-16 00:25:34 -0400 | [diff] [blame] | 143 | if ((flags & TRANSPORT_PUSH_ALL) && refspec) |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 144 | usage(push_usage); |
| 145 | |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 146 | return do_push(repo, flags); |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 147 | } |