builtin-push.c: Fix typo: "anythig" -> "anything"
[git/jnareb-git.git] / builtin-push.c
blobbbf019850e5b93a2e36584fc00573dd180a19be0
1 /*
2 * "git push"
3 */
4 #include "cache.h"
5 #include "refs.h"
6 #include "run-command.h"
7 #include "builtin.h"
8 #include "remote.h"
9 #include "transport.h"
10 #include "parse-options.h"
12 static const char * const push_usage[] = {
13 "git push [--all | --mirror] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=<repository>] [-f | --force] [-v] [<repository> <refspec>...]",
14 NULL,
17 static int thin;
18 static const char *receivepack;
20 static const char **refspec;
21 static int refspec_nr;
23 static void add_refspec(const char *ref)
25 int nr = refspec_nr + 1;
26 refspec = xrealloc(refspec, nr * sizeof(char *));
27 refspec[nr-1] = ref;
28 refspec_nr = nr;
31 static void set_refspecs(const char **refs, int nr)
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;
47 add_refspec(ref);
51 static void setup_push_tracking(void)
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);
67 static 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:",
76 " 'nothing' : Do not push anything",
77 " 'matching' : Push all matching branches (default)",
78 " 'tracking' : Push the current branch to whatever it is tracking",
79 " 'current' : Push the current branch"
82 static void warn_unconfigured_push(void)
84 int i;
85 for (i = 0; i < ARRAY_SIZE(warn_unconfigured_push_msg); i++)
86 warning("%s", warn_unconfigured_push_msg[i]);
89 static void setup_default_push_refspecs(void)
91 git_config(git_default_config, NULL);
92 switch (push_default) {
93 case PUSH_DEFAULT_UNSPECIFIED:
94 warn_unconfigured_push();
95 /* fallthrough */
97 case PUSH_DEFAULT_MATCHING:
98 add_refspec(":");
99 break;
101 case PUSH_DEFAULT_TRACKING:
102 setup_push_tracking();
103 break;
105 case PUSH_DEFAULT_CURRENT:
106 add_refspec("HEAD");
107 break;
109 case PUSH_DEFAULT_NOTHING:
110 die("You didn't specify any refspecs to push, and "
111 "push.default is \"nothing\".");
112 break;
116 static int do_push(const char *repo, int flags)
118 int i, errs;
119 struct remote *remote = remote_get(repo);
121 if (!remote)
122 die("bad repository '%s'", repo);
124 if (remote->mirror)
125 flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
127 if ((flags & TRANSPORT_PUSH_ALL) && refspec) {
128 if (!strcmp(*refspec, "refs/tags/*"))
129 return error("--all and --tags are incompatible");
130 return error("--all can't be combined with refspecs");
133 if ((flags & TRANSPORT_PUSH_MIRROR) && refspec) {
134 if (!strcmp(*refspec, "refs/tags/*"))
135 return error("--mirror and --tags are incompatible");
136 return error("--mirror can't be combined with refspecs");
139 if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
140 (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
141 return error("--all and --mirror are incompatible");
144 if (!refspec && !(flags & TRANSPORT_PUSH_ALL)) {
145 if (remote->push_refspec_nr) {
146 refspec = remote->push_refspec;
147 refspec_nr = remote->push_refspec_nr;
148 } else if (!(flags & TRANSPORT_PUSH_MIRROR))
149 setup_default_push_refspecs();
151 errs = 0;
152 for (i = 0; i < remote->url_nr; i++) {
153 struct transport *transport =
154 transport_get(remote, remote->url[i]);
155 int err;
156 if (receivepack)
157 transport_set_option(transport,
158 TRANS_OPT_RECEIVEPACK, receivepack);
159 if (thin)
160 transport_set_option(transport, TRANS_OPT_THIN, "yes");
162 if (flags & TRANSPORT_PUSH_VERBOSE)
163 fprintf(stderr, "Pushing to %s\n", remote->url[i]);
164 err = transport_push(transport, refspec_nr, refspec, flags);
165 err |= transport_disconnect(transport);
167 if (!err)
168 continue;
170 error("failed to push some refs to '%s'", remote->url[i]);
171 errs++;
173 return !!errs;
176 int cmd_push(int argc, const char **argv, const char *prefix)
178 int flags = 0;
179 int tags = 0;
180 int rc;
181 const char *repo = NULL; /* default repository */
183 struct option options[] = {
184 OPT_BIT('v', "verbose", &flags, "be verbose", TRANSPORT_PUSH_VERBOSE),
185 OPT_STRING( 0 , "repo", &repo, "repository", "repository"),
186 OPT_BIT( 0 , "all", &flags, "push all refs", TRANSPORT_PUSH_ALL),
187 OPT_BIT( 0 , "mirror", &flags, "mirror all refs",
188 (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),
189 OPT_BOOLEAN( 0 , "tags", &tags, "push tags"),
190 OPT_BIT( 0 , "dry-run", &flags, "dry run", TRANSPORT_PUSH_DRY_RUN),
191 OPT_BIT('f', "force", &flags, "force updates", TRANSPORT_PUSH_FORCE),
192 OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"),
193 OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", "receive pack program"),
194 OPT_STRING( 0 , "exec", &receivepack, "receive-pack", "receive pack program"),
195 OPT_END()
198 argc = parse_options(argc, argv, options, push_usage, 0);
200 if (tags)
201 add_refspec("refs/tags/*");
203 if (argc > 0) {
204 repo = argv[0];
205 set_refspecs(argv + 1, argc - 1);
208 rc = do_push(repo, flags);
209 if (rc == -1)
210 usage_with_options(push_usage, options);
211 else
212 return rc;