blob: 4b39ef3852a5dcb9b099527d4aafc33ba3bb6da1 [file] [log] [blame]
Linus Torvalds755225d2006-04-29 21:22:49 -07001/*
2 * "git push"
3 */
4#include "cache.h"
5#include "refs.h"
6#include "run-command.h"
7#include "builtin.h"
Daniel Barkalow5751f492007-05-12 11:45:53 -04008#include "remote.h"
Daniel Barkalow9b288512007-09-10 23:03:04 -04009#include "transport.h"
Linus Torvalds755225d2006-04-29 21:22:49 -070010
Brian Ewins11f24412007-10-11 20:32:27 +010011static const char push_usage[] = "git-push [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]";
Linus Torvalds755225d2006-04-29 21:22:49 -070012
Shawn O. Pearce18184f72007-10-16 00:25:34 -040013static int thin, verbose;
Uwe Kleine-Königd23842f2007-01-19 13:49:27 +010014static const char *receivepack;
Linus Torvalds755225d2006-04-29 21:22:49 -070015
David Rientjes96f1e582006-08-15 10:23:48 -070016static const char **refspec;
17static int refspec_nr;
Linus Torvalds755225d2006-04-29 21:22:49 -070018
19static 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 Torvalds755225d2006-04-29 21:22:49 -070027static void set_refspecs(const char **refs, int nr)
28{
Daniel Barkalow8558fd92007-05-25 01:20:56 -040029 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 Hamano411fb8b2006-12-13 10:03:39 -080042 }
Daniel Barkalow8558fd92007-05-25 01:20:56 -040043 add_refspec(ref);
Linus Torvalds755225d2006-04-29 21:22:49 -070044 }
Linus Torvalds755225d2006-04-29 21:22:49 -070045}
46
Daniel Barkalow9b288512007-09-10 23:03:04 -040047static int do_push(const char *repo, int flags)
Linus Torvalds755225d2006-04-29 21:22:49 -070048{
Daniel Barkalow5751f492007-05-12 11:45:53 -040049 int i, errs;
Daniel Barkalow5751f492007-05-12 11:45:53 -040050 struct remote *remote = remote_get(repo);
Linus Torvalds755225d2006-04-29 21:22:49 -070051
Daniel Barkalow5751f492007-05-12 11:45:53 -040052 if (!remote)
Linus Torvalds755225d2006-04-29 21:22:49 -070053 die("bad repository '%s'", repo);
54
Shawn O. Pearce18184f72007-10-16 00:25:34 -040055 if (!refspec
56 && !(flags & TRANSPORT_PUSH_ALL)
57 && remote->push_refspec_nr) {
Daniel Barkalow8558fd92007-05-25 01:20:56 -040058 refspec = remote->push_refspec;
59 refspec_nr = remote->push_refspec_nr;
Daniel Barkalow5751f492007-05-12 11:45:53 -040060 }
Junio C Hamanofd1d1b02007-04-06 23:04:53 -070061 errs = 0;
Shawn O. Pearce28b91f82007-09-19 00:49:27 -040062 for (i = 0; i < remote->url_nr; i++) {
Daniel Barkalow9b288512007-09-10 23:03:04 -040063 struct transport *transport =
Shawn O. Pearce28b91f82007-09-19 00:49:27 -040064 transport_get(remote, remote->url[i]);
Pierre Habouzit60b7f382006-08-23 12:39:10 +020065 int err;
Daniel Barkalow9b288512007-09-10 23:03:04 -040066 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 Torvaldsbcc785f2006-10-30 08:28:59 -080072 if (verbose)
Shawn O. Pearce28b91f82007-09-19 00:49:27 -040073 fprintf(stderr, "Pushing to %s\n", remote->url[i]);
Daniel Barkalow9b288512007-09-10 23:03:04 -040074 err = transport_push(transport, refspec_nr, refspec, flags);
75 err |= transport_disconnect(transport);
76
Pierre Habouzit60b7f382006-08-23 12:39:10 +020077 if (!err)
Linus Torvalds755225d2006-04-29 21:22:49 -070078 continue;
Junio C Hamano39878b02007-04-06 23:04:55 -070079
Shawn O. Pearce28b91f82007-09-19 00:49:27 -040080 error("failed to push to '%s'", remote->url[i]);
Junio C Hamanofd1d1b02007-04-06 23:04:53 -070081 errs++;
Linus Torvalds755225d2006-04-29 21:22:49 -070082 }
Junio C Hamanofd1d1b02007-04-06 23:04:53 -070083 return !!errs;
Linus Torvalds755225d2006-04-29 21:22:49 -070084}
85
Linus Torvaldsa633fca2006-07-28 22:44:25 -070086int cmd_push(int argc, const char **argv, const char *prefix)
Linus Torvalds755225d2006-04-29 21:22:49 -070087{
88 int i;
Daniel Barkalow9b288512007-09-10 23:03:04 -040089 int flags = 0;
Daniel Barkalow5751f492007-05-12 11:45:53 -040090 const char *repo = NULL; /* default repository */
Linus Torvalds755225d2006-04-29 21:22:49 -070091
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 Torvaldsbcc785f2006-10-30 08:28:59 -0800100 if (!strcmp(arg, "-v")) {
101 verbose=1;
102 continue;
103 }
Junio C Hamanocc44c762007-02-20 01:53:29 -0800104 if (!prefixcmp(arg, "--repo=")) {
Linus Torvaldsbcc785f2006-10-30 08:28:59 -0800105 repo = arg+7;
106 continue;
107 }
Linus Torvalds755225d2006-04-29 21:22:49 -0700108 if (!strcmp(arg, "--all")) {
Daniel Barkalow9b288512007-09-10 23:03:04 -0400109 flags |= TRANSPORT_PUSH_ALL;
Linus Torvalds755225d2006-04-29 21:22:49 -0700110 continue;
111 }
Brian Ewins11f24412007-10-11 20:32:27 +0100112 if (!strcmp(arg, "--dry-run")) {
Shawn O. Pearce2e13e5d2007-10-16 00:15:25 -0400113 flags |= TRANSPORT_PUSH_DRY_RUN;
Brian Ewins11f24412007-10-11 20:32:27 +0100114 continue;
115 }
Linus Torvalds755225d2006-04-29 21:22:49 -0700116 if (!strcmp(arg, "--tags")) {
Daniel Barkalow8558fd92007-05-25 01:20:56 -0400117 add_refspec("refs/tags/*");
Linus Torvalds755225d2006-04-29 21:22:49 -0700118 continue;
119 }
Jeff King8f615492006-08-02 11:28:16 -0400120 if (!strcmp(arg, "--force") || !strcmp(arg, "-f")) {
Daniel Barkalow9b288512007-09-10 23:03:04 -0400121 flags |= TRANSPORT_PUSH_FORCE;
Linus Torvalds755225d2006-04-29 21:22:49 -0700122 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 Hamanocc44c762007-02-20 01:53:29 -0800132 if (!prefixcmp(arg, "--receive-pack=")) {
Daniel Barkalow9b288512007-09-10 23:03:04 -0400133 receivepack = arg + 15;
Uwe Kleine-Königd23842f2007-01-19 13:49:27 +0100134 continue;
135 }
Junio C Hamanocc44c762007-02-20 01:53:29 -0800136 if (!prefixcmp(arg, "--exec=")) {
Daniel Barkalow9b288512007-09-10 23:03:04 -0400137 receivepack = arg + 7;
Linus Torvalds755225d2006-04-29 21:22:49 -0700138 continue;
139 }
140 usage(push_usage);
141 }
142 set_refspecs(argv + i, argc - i);
Shawn O. Pearce18184f72007-10-16 00:25:34 -0400143 if ((flags & TRANSPORT_PUSH_ALL) && refspec)
Daniel Barkalow8558fd92007-05-25 01:20:56 -0400144 usage(push_usage);
145
Daniel Barkalow9b288512007-09-10 23:03:04 -0400146 return do_push(repo, flags);
Linus Torvalds755225d2006-04-29 21:22:49 -0700147}