Merge branch 'maint'
[git/git.git] / builtin-push.c
CommitLineData
755225de
LT
1/*
2 * "git push"
3 */
4#include "cache.h"
5#include "refs.h"
6#include "run-command.h"
7#include "builtin.h"
5751f490 8#include "remote.h"
9b288516 9#include "transport.h"
378c4832 10#include "parse-options.h"
755225de 11
378c4832 12static const char * const push_usage[] = {
bf07cc58 13 "git push [--all | --mirror] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=<repository>] [-f | --force] [-v] [<repository> <refspec>...]",
378c4832
DB
14 NULL,
15};
755225de 16
c29c1b40 17static int thin;
d23842fd 18static const char *receivepack;
755225de 19
96f1e58f
DR
20static const char **refspec;
21static int refspec_nr;
755225de
LT
22
23static void add_refspec(const char *ref)
24{
25 int nr = refspec_nr + 1;
26 refspec = xrealloc(refspec, nr * sizeof(char *));
27 refspec[nr-1] = ref;
28 refspec_nr = nr;
29}
30
755225de
LT
31static void set_refspecs(const char **refs, int nr)
32{
8558fd9e
DB
33 int i;
34 for (i = 0; i < nr; i++) {
35 const char *ref = refs[i];
36 if (!strcmp("tag", ref)) {
37 char *tag;
38 int len;
39 if (nr <= ++i)
40 die("tag shorthand without <tag>");
41 len = strlen(refs[i]) + 11;
42 tag = xmalloc(len);
43 strcpy(tag, "refs/tags/");
44 strcat(tag, refs[i]);
45 ref = tag;
411fb8ba 46 }
8558fd9e 47 add_refspec(ref);
755225de 48 }
755225de
LT
49}
50
52153747
FAG
51static void setup_push_tracking(void)
52{
53 struct strbuf refspec = STRBUF_INIT;
54 struct branch *branch = branch_get(NULL);
55 if (!branch)
56 die("You are not currently on a branch.");
57 if (!branch->merge_nr)
58 die("The current branch %s is not tracking anything.",
59 branch->name);
60 if (branch->merge_nr != 1)
61 die("The current branch %s is tracking multiple branches, "
62 "refusing to push.", branch->name);
63 strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src);
64 add_refspec(refspec.buf);
65}
66
665d3e8f
FAG
67static const char *warn_unconfigured_push_msg[] = {
68 "You did not specify any refspecs to push, and the current remote",
69 "has not configured any push refspecs. The default action in this",
70 "case is to push all matching refspecs, that is, all branches",
71 "that exist both locally and remotely will be updated. This may",
72 "not necessarily be what you want to happen.",
73 "",
74 "You can specify what action you want to take in this case, and",
75 "avoid seeing this message again, by configuring 'push.default' to:",
b2655cda 76 " 'nothing' : Do not push anything",
665d3e8f
FAG
77 " 'matching' : Push all matching branches (default)",
78 " 'tracking' : Push the current branch to whatever it is tracking",
79 " 'current' : Push the current branch"
80};
81
82static void warn_unconfigured_push(void)
83{
84 int i;
85 for (i = 0; i < ARRAY_SIZE(warn_unconfigured_push_msg); i++)
86 warning("%s", warn_unconfigured_push_msg[i]);
87}
88
52153747
FAG
89static void setup_default_push_refspecs(void)
90{
91 git_config(git_default_config, NULL);
92 switch (push_default) {
93 case PUSH_DEFAULT_UNSPECIFIED:
665d3e8f 94 warn_unconfigured_push();
52153747
FAG
95 /* fallthrough */
96
97 case PUSH_DEFAULT_MATCHING:
98 add_refspec(":");
99 break;
100
101 case PUSH_DEFAULT_TRACKING:
102 setup_push_tracking();
103 break;
104
105 case PUSH_DEFAULT_CURRENT:
106 add_refspec("HEAD");
107 break;
108
109 case PUSH_DEFAULT_NOTHING:
110 die("You didn't specify any refspecs to push, and "
111 "push.default is \"nothing\".");
112 break;
113 }
114}
115
9b288516 116static int do_push(const char *repo, int flags)
755225de 117{
5751f490 118 int i, errs;
5751f490 119 struct remote *remote = remote_get(repo);
755225de 120
fa685bdf
DB
121 if (!remote) {
122 if (repo)
123 die("bad repository '%s'", repo);
124 die("No destination configured to push to.");
125 }
755225de 126
84bb2dfd
PB
127 if (remote->mirror)
128 flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
129
b259f09b
MZ
130 if ((flags & TRANSPORT_PUSH_ALL) && refspec) {
131 if (!strcmp(*refspec, "refs/tags/*"))
132 return error("--all and --tags are incompatible");
133 return error("--all can't be combined with refspecs");
134 }
135
136 if ((flags & TRANSPORT_PUSH_MIRROR) && refspec) {
137 if (!strcmp(*refspec, "refs/tags/*"))
138 return error("--mirror and --tags are incompatible");
139 return error("--mirror can't be combined with refspecs");
140 }
84bb2dfd
PB
141
142 if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
143 (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
144 return error("--all and --mirror are incompatible");
145 }
146
52153747
FAG
147 if (!refspec && !(flags & TRANSPORT_PUSH_ALL)) {
148 if (remote->push_refspec_nr) {
149 refspec = remote->push_refspec;
150 refspec_nr = remote->push_refspec_nr;
151 } else if (!(flags & TRANSPORT_PUSH_MIRROR))
152 setup_default_push_refspecs();
5751f490 153 }
fd1d1b05 154 errs = 0;
28b91f8a 155 for (i = 0; i < remote->url_nr; i++) {
9b288516 156 struct transport *transport =
28b91f8a 157 transport_get(remote, remote->url[i]);
60b7f38e 158 int err;
9b288516
DB
159 if (receivepack)
160 transport_set_option(transport,
161 TRANS_OPT_RECEIVEPACK, receivepack);
162 if (thin)
163 transport_set_option(transport, TRANS_OPT_THIN, "yes");
164
c29c1b40 165 if (flags & TRANSPORT_PUSH_VERBOSE)
28b91f8a 166 fprintf(stderr, "Pushing to %s\n", remote->url[i]);
9b288516
DB
167 err = transport_push(transport, refspec_nr, refspec, flags);
168 err |= transport_disconnect(transport);
169
60b7f38e 170 if (!err)
755225de 171 continue;
39878b0c 172
2b8130c3 173 error("failed to push some refs to '%s'", remote->url[i]);
fd1d1b05 174 errs++;
755225de 175 }
fd1d1b05 176 return !!errs;
755225de
LT
177}
178
a633fca0 179int cmd_push(int argc, const char **argv, const char *prefix)
755225de 180{
9b288516 181 int flags = 0;
378c4832 182 int tags = 0;
84bb2dfd 183 int rc;
5751f490 184 const char *repo = NULL; /* default repository */
755225de 185
378c4832 186 struct option options[] = {
c29c1b40 187 OPT_BIT('v', "verbose", &flags, "be verbose", TRANSPORT_PUSH_VERBOSE),
378c4832 188 OPT_STRING( 0 , "repo", &repo, "repository", "repository"),
c29c1b40
MB
189 OPT_BIT( 0 , "all", &flags, "push all refs", TRANSPORT_PUSH_ALL),
190 OPT_BIT( 0 , "mirror", &flags, "mirror all refs",
191 (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),
378c4832 192 OPT_BOOLEAN( 0 , "tags", &tags, "push tags"),
c29c1b40
MB
193 OPT_BIT( 0 , "dry-run", &flags, "dry run", TRANSPORT_PUSH_DRY_RUN),
194 OPT_BIT('f', "force", &flags, "force updates", TRANSPORT_PUSH_FORCE),
378c4832
DB
195 OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"),
196 OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", "receive pack program"),
197 OPT_STRING( 0 , "exec", &receivepack, "receive-pack", "receive pack program"),
198 OPT_END()
199 };
755225de 200
37782920 201 argc = parse_options(argc, argv, prefix, options, push_usage, 0);
378c4832 202
378c4832
DB
203 if (tags)
204 add_refspec("refs/tags/*");
378c4832
DB
205
206 if (argc > 0) {
207 repo = argv[0];
208 set_refspecs(argv + 1, argc - 1);
755225de 209 }
8558fd9e 210
84bb2dfd
PB
211 rc = do_push(repo, flags);
212 if (rc == -1)
94c89ba6 213 usage_with_options(push_usage, options);
84bb2dfd
PB
214 else
215 return rc;
755225de 216}