1/*
2 * "git push"
3 */
4#include "cache.h"
5#include "config.h"
6#include "refs.h"
7#include "refspec.h"
8#include "run-command.h"
9#include "builtin.h"
10#include "remote.h"
11#include "transport.h"
12#include "parse-options.h"
13#include "submodule.h"
14#include "submodule-config.h"
15#include "send-pack.h"
16#include "color.h"
17
18static const char * const push_usage[] = {
19 N_("git push [<options>] [<repository> [<refspec>...]]"),
20 NULL,
21};
22
23static int push_use_color = -1;
24static char push_colors[][COLOR_MAXLEN] = {
25 GIT_COLOR_RESET,
26 GIT_COLOR_RED, /* ERROR */
27};
28
29enum color_push {
30 PUSH_COLOR_RESET = 0,
31 PUSH_COLOR_ERROR = 1
32};
33
34static int parse_push_color_slot(const char *slot)
35{
36 if (!strcasecmp(slot, "reset"))
37 return PUSH_COLOR_RESET;
38 if (!strcasecmp(slot, "error"))
39 return PUSH_COLOR_ERROR;
40 return -1;
41}
42
43static const char *push_get_color(enum color_push ix)
44{
45 if (want_color_stderr(push_use_color))
46 return push_colors[ix];
47 return "";
48}
49
50static int thin = 1;
51static int deleterefs;
52static const char *receivepack;
53static int verbosity;
54static int progress = -1;
55static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
56static enum transport_family family;
57
58static struct push_cas_option cas;
59
60static const char **refspec;
61static int refspec_nr;
62static int refspec_alloc;
63
64static struct string_list push_options_config = STRING_LIST_INIT_DUP;
65
66static void add_refspec(const char *ref)
67{
68 refspec_nr++;
69 ALLOC_GROW(refspec, refspec_nr, refspec_alloc);
70 refspec[refspec_nr-1] = ref;
71}
72
73static const char *map_refspec(const char *ref,
74 struct remote *remote, struct ref *local_refs)
75{
76 struct ref *matched = NULL;
77
78 /* Does "ref" uniquely name our ref? */
79 if (count_refspec_match(ref, local_refs, &matched) != 1)
80 return ref;
81
82 if (remote->push.nr) {
83 struct refspec_item query;
84 memset(&query, 0, sizeof(struct refspec_item));
85 query.src = matched->name;
86 if (!query_refspecs(remote->push.items, remote->push.nr, &query) &&
87 query.dst) {
88 struct strbuf buf = STRBUF_INIT;
89 strbuf_addf(&buf, "%s%s:%s",
90 query.force ? "+" : "",
91 query.src, query.dst);
92 return strbuf_detach(&buf, NULL);
93 }
94 }
95
96 if (push_default == PUSH_DEFAULT_UPSTREAM &&
97 starts_with(matched->name, "refs/heads/")) {
98 struct branch *branch = branch_get(matched->name + 11);
99 if (branch->merge_nr == 1 && branch->merge[0]->src) {
100 struct strbuf buf = STRBUF_INIT;
101 strbuf_addf(&buf, "%s:%s",
102 ref, branch->merge[0]->src);
103 return strbuf_detach(&buf, NULL);
104 }
105 }
106
107 return ref;
108}
109
110static void set_refspecs(const char **refs, int nr, const char *repo)
111{
112 struct remote *remote = NULL;
113 struct ref *local_refs = NULL;
114 int i;
115
116 for (i = 0; i < nr; i++) {
117 const char *ref = refs[i];
118 if (!strcmp("tag", ref)) {
119 struct strbuf tagref = STRBUF_INIT;
120 if (nr <= ++i)
121 die(_("tag shorthand without <tag>"));
122 ref = refs[i];
123 if (deleterefs)
124 strbuf_addf(&tagref, ":refs/tags/%s", ref);
125 else
126 strbuf_addf(&tagref, "refs/tags/%s", ref);
127 ref = strbuf_detach(&tagref, NULL);
128 } else if (deleterefs) {
129 struct strbuf delref = STRBUF_INIT;
130 if (strchr(ref, ':'))
131 die(_("--delete only accepts plain target ref names"));
132 strbuf_addf(&delref, ":%s", ref);
133 ref = strbuf_detach(&delref, NULL);
134 } else if (!strchr(ref, ':')) {
135 if (!remote) {
136 /* lazily grab remote and local_refs */
137 remote = remote_get(repo);
138 local_refs = get_local_heads();
139 }
140 ref = map_refspec(ref, remote, local_refs);
141 }
142 add_refspec(ref);
143 }
144}
145
146static int push_url_of_remote(struct remote *remote, const char ***url_p)
147{
148 if (remote->pushurl_nr) {
149 *url_p = remote->pushurl;
150 return remote->pushurl_nr;
151 }
152 *url_p = remote->url;
153 return remote->url_nr;
154}
155
156static NORETURN int die_push_simple(struct branch *branch, struct remote *remote) {
157 /*
158 * There's no point in using shorten_unambiguous_ref here,
159 * as the ambiguity would be on the remote side, not what
160 * we have locally. Plus, this is supposed to be the simple
161 * mode. If the user is doing something crazy like setting
162 * upstream to a non-branch, we should probably be showing
163 * them the big ugly fully qualified ref.
164 */
165 const char *advice_maybe = "";
166 const char *short_upstream = branch->merge[0]->src;
167
168 skip_prefix(short_upstream, "refs/heads/", &short_upstream);
169
170 /*
171 * Don't show advice for people who explicitly set
172 * push.default.
173 */
174 if (push_default == PUSH_DEFAULT_UNSPECIFIED)
175 advice_maybe = _("\n"
176 "To choose either option permanently, "
177 "see push.default in 'git help config'.");
178 die(_("The upstream branch of your current branch does not match\n"
179 "the name of your current branch. To push to the upstream branch\n"
180 "on the remote, use\n"
181 "\n"
182 " git push %s HEAD:%s\n"
183 "\n"
184 "To push to the branch of the same name on the remote, use\n"
185 "\n"
186 " git push %s %s\n"
187 "%s"),
188 remote->name, short_upstream,
189 remote->name, branch->name, advice_maybe);
190}
191
192static const char message_detached_head_die[] =
193 N_("You are not currently on a branch.\n"
194 "To push the history leading to the current (detached HEAD)\n"
195 "state now, use\n"
196 "\n"
197 " git push %s HEAD:<name-of-remote-branch>\n");
198
199static void setup_push_upstream(struct remote *remote, struct branch *branch,
200 int triangular, int simple)
201{
202 struct strbuf refspec = STRBUF_INIT;
203
204 if (!branch)
205 die(_(message_detached_head_die), remote->name);
206 if (!branch->merge_nr || !branch->merge || !branch->remote_name)
207 die(_("The current branch %s has no upstream branch.\n"
208 "To push the current branch and set the remote as upstream, use\n"
209 "\n"
210 " git push --set-upstream %s %s\n"),
211 branch->name,
212 remote->name,
213 branch->name);
214 if (branch->merge_nr != 1)
215 die(_("The current branch %s has multiple upstream branches, "
216 "refusing to push."), branch->name);
217 if (triangular)
218 die(_("You are pushing to remote '%s', which is not the upstream of\n"
219 "your current branch '%s', without telling me what to push\n"
220 "to update which remote branch."),
221 remote->name, branch->name);
222
223 if (simple) {
224 /* Additional safety */
225 if (strcmp(branch->refname, branch->merge[0]->src))
226 die_push_simple(branch, remote);
227 }
228
229 strbuf_addf(&refspec, "%s:%s", branch->refname, branch->merge[0]->src);
230 add_refspec(refspec.buf);
231}
232
233static void setup_push_current(struct remote *remote, struct branch *branch)
234{
235 struct strbuf refspec = STRBUF_INIT;
236
237 if (!branch)
238 die(_(message_detached_head_die), remote->name);
239 strbuf_addf(&refspec, "%s:%s", branch->refname, branch->refname);
240 add_refspec(refspec.buf);
241}
242
243static int is_workflow_triangular(struct remote *remote)
244{
245 struct remote *fetch_remote = remote_get(NULL);
246 return (fetch_remote && fetch_remote != remote);
247}
248
249static void setup_default_push_refspecs(struct remote *remote)
250{
251 struct branch *branch = branch_get(NULL);
252 int triangular = is_workflow_triangular(remote);
253
254 switch (push_default) {
255 default:
256 case PUSH_DEFAULT_MATCHING:
257 add_refspec(":");
258 break;
259
260 case PUSH_DEFAULT_UNSPECIFIED:
261 case PUSH_DEFAULT_SIMPLE:
262 if (triangular)
263 setup_push_current(remote, branch);
264 else
265 setup_push_upstream(remote, branch, triangular, 1);
266 break;
267
268 case PUSH_DEFAULT_UPSTREAM:
269 setup_push_upstream(remote, branch, triangular, 0);
270 break;
271
272 case PUSH_DEFAULT_CURRENT:
273 setup_push_current(remote, branch);
274 break;
275
276 case PUSH_DEFAULT_NOTHING:
277 die(_("You didn't specify any refspecs to push, and "
278 "push.default is \"nothing\"."));
279 break;
280 }
281}
282
283static const char message_advice_pull_before_push[] =
284 N_("Updates were rejected because the tip of your current branch is behind\n"
285 "its remote counterpart. Integrate the remote changes (e.g.\n"
286 "'git pull ...') before pushing again.\n"
287 "See the 'Note about fast-forwards' in 'git push --help' for details.");
288
289static const char message_advice_checkout_pull_push[] =
290 N_("Updates were rejected because a pushed branch tip is behind its remote\n"
291 "counterpart. Check out this branch and integrate the remote changes\n"
292 "(e.g. 'git pull ...') before pushing again.\n"
293 "See the 'Note about fast-forwards' in 'git push --help' for details.");
294
295static const char message_advice_ref_fetch_first[] =
296 N_("Updates were rejected because the remote contains work that you do\n"
297 "not have locally. This is usually caused by another repository pushing\n"
298 "to the same ref. You may want to first integrate the remote changes\n"
299 "(e.g., 'git pull ...') before pushing again.\n"
300 "See the 'Note about fast-forwards' in 'git push --help' for details.");
301
302static const char message_advice_ref_already_exists[] =
303 N_("Updates were rejected because the tag already exists in the remote.");
304
305static const char message_advice_ref_needs_force[] =
306 N_("You cannot update a remote ref that points at a non-commit object,\n"
307 "or update a remote ref to make it point at a non-commit object,\n"
308 "without using the '--force' option.\n");
309
310static void advise_pull_before_push(void)
311{
312 if (!advice_push_non_ff_current || !advice_push_update_rejected)
313 return;
314 advise(_(message_advice_pull_before_push));
315}
316
317static void advise_checkout_pull_push(void)
318{
319 if (!advice_push_non_ff_matching || !advice_push_update_rejected)
320 return;
321 advise(_(message_advice_checkout_pull_push));
322}
323
324static void advise_ref_already_exists(void)
325{
326 if (!advice_push_already_exists || !advice_push_update_rejected)
327 return;
328 advise(_(message_advice_ref_already_exists));
329}
330
331static void advise_ref_fetch_first(void)
332{
333 if (!advice_push_fetch_first || !advice_push_update_rejected)
334 return;
335 advise(_(message_advice_ref_fetch_first));
336}
337
338static void advise_ref_needs_force(void)
339{
340 if (!advice_push_needs_force || !advice_push_update_rejected)
341 return;
342 advise(_(message_advice_ref_needs_force));
343}
344
345static int push_with_options(struct transport *transport, int flags)
346{
347 int err;
348 unsigned int reject_reasons;
349
350 transport_set_verbosity(transport, verbosity, progress);
351 transport->family = family;
352
353 if (receivepack)
354 transport_set_option(transport,
355 TRANS_OPT_RECEIVEPACK, receivepack);
356 transport_set_option(transport, TRANS_OPT_THIN, thin ? "yes" : NULL);
357
358 if (!is_empty_cas(&cas)) {
359 if (!transport->smart_options)
360 die("underlying transport does not support --%s option",
361 CAS_OPT_NAME);
362 transport->smart_options->cas = &cas;
363 }
364
365 if (verbosity > 0)
366 fprintf(stderr, _("Pushing to %s\n"), transport->url);
367 err = transport_push(transport, refspec_nr, refspec, flags,
368 &reject_reasons);
369 if (err != 0) {
370 fprintf(stderr, "%s", push_get_color(PUSH_COLOR_ERROR));
371 error(_("failed to push some refs to '%s'"), transport->url);
372 fprintf(stderr, "%s", push_get_color(PUSH_COLOR_RESET));
373 }
374
375 err |= transport_disconnect(transport);
376 if (!err)
377 return 0;
378
379 if (reject_reasons & REJECT_NON_FF_HEAD) {
380 advise_pull_before_push();
381 } else if (reject_reasons & REJECT_NON_FF_OTHER) {
382 advise_checkout_pull_push();
383 } else if (reject_reasons & REJECT_ALREADY_EXISTS) {
384 advise_ref_already_exists();
385 } else if (reject_reasons & REJECT_FETCH_FIRST) {
386 advise_ref_fetch_first();
387 } else if (reject_reasons & REJECT_NEEDS_FORCE) {
388 advise_ref_needs_force();
389 }
390
391 return 1;
392}
393
394static int do_push(const char *repo, int flags,
395 const struct string_list *push_options)
396{
397 int i, errs;
398 struct remote *remote = pushremote_get(repo);
399 const char **url;
400 int url_nr;
401
402 if (!remote) {
403 if (repo)
404 die(_("bad repository '%s'"), repo);
405 die(_("No configured push destination.\n"
406 "Either specify the URL from the command-line or configure a remote repository using\n"
407 "\n"
408 " git remote add <name> <url>\n"
409 "\n"
410 "and then push using the remote name\n"
411 "\n"
412 " git push <name>\n"));
413 }
414
415 if (remote->mirror)
416 flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
417
418 if (push_options->nr)
419 flags |= TRANSPORT_PUSH_OPTIONS;
420
421 if ((flags & TRANSPORT_PUSH_ALL) && refspec) {
422 if (!strcmp(*refspec, "refs/tags/*"))
423 return error(_("--all and --tags are incompatible"));
424 return error(_("--all can't be combined with refspecs"));
425 }
426
427 if ((flags & TRANSPORT_PUSH_MIRROR) && refspec) {
428 if (!strcmp(*refspec, "refs/tags/*"))
429 return error(_("--mirror and --tags are incompatible"));
430 return error(_("--mirror can't be combined with refspecs"));
431 }
432
433 if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
434 (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
435 return error(_("--all and --mirror are incompatible"));
436 }
437
438 if (!refspec && !(flags & TRANSPORT_PUSH_ALL)) {
439 if (remote->push.raw_nr) {
440 refspec = remote->push.raw;
441 refspec_nr = remote->push.raw_nr;
442 } else if (!(flags & TRANSPORT_PUSH_MIRROR))
443 setup_default_push_refspecs(remote);
444 }
445 errs = 0;
446 url_nr = push_url_of_remote(remote, &url);
447 if (url_nr) {
448 for (i = 0; i < url_nr; i++) {
449 struct transport *transport =
450 transport_get(remote, url[i]);
451 if (flags & TRANSPORT_PUSH_OPTIONS)
452 transport->push_options = push_options;
453 if (push_with_options(transport, flags))
454 errs++;
455 }
456 } else {
457 struct transport *transport =
458 transport_get(remote, NULL);
459 if (flags & TRANSPORT_PUSH_OPTIONS)
460 transport->push_options = push_options;
461 if (push_with_options(transport, flags))
462 errs++;
463 }
464 return !!errs;
465}
466
467static int option_parse_recurse_submodules(const struct option *opt,
468 const char *arg, int unset)
469{
470 int *recurse_submodules = opt->value;
471
472 if (unset)
473 *recurse_submodules = RECURSE_SUBMODULES_OFF;
474 else if (arg)
475 *recurse_submodules = parse_push_recurse_submodules_arg(opt->long_name, arg);
476 else
477 die("%s missing parameter", opt->long_name);
478
479 return 0;
480}
481
482static void set_push_cert_flags(int *flags, int v)
483{
484 switch (v) {
485 case SEND_PACK_PUSH_CERT_NEVER:
486 *flags &= ~(TRANSPORT_PUSH_CERT_ALWAYS | TRANSPORT_PUSH_CERT_IF_ASKED);
487 break;
488 case SEND_PACK_PUSH_CERT_ALWAYS:
489 *flags |= TRANSPORT_PUSH_CERT_ALWAYS;
490 *flags &= ~TRANSPORT_PUSH_CERT_IF_ASKED;
491 break;
492 case SEND_PACK_PUSH_CERT_IF_ASKED:
493 *flags |= TRANSPORT_PUSH_CERT_IF_ASKED;
494 *flags &= ~TRANSPORT_PUSH_CERT_ALWAYS;
495 break;
496 }
497}
498
499
500static int git_push_config(const char *k, const char *v, void *cb)
501{
502 const char *slot_name;
503 int *flags = cb;
504 int status;
505
506 status = git_gpg_config(k, v, NULL);
507 if (status)
508 return status;
509
510 if (!strcmp(k, "push.followtags")) {
511 if (git_config_bool(k, v))
512 *flags |= TRANSPORT_PUSH_FOLLOW_TAGS;
513 else
514 *flags &= ~TRANSPORT_PUSH_FOLLOW_TAGS;
515 return 0;
516 } else if (!strcmp(k, "push.gpgsign")) {
517 const char *value;
518 if (!git_config_get_value("push.gpgsign", &value)) {
519 switch (git_parse_maybe_bool(value)) {
520 case 0:
521 set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_NEVER);
522 break;
523 case 1:
524 set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_ALWAYS);
525 break;
526 default:
527 if (value && !strcasecmp(value, "if-asked"))
528 set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_IF_ASKED);
529 else
530 return error("Invalid value for '%s'", k);
531 }
532 }
533 } else if (!strcmp(k, "push.recursesubmodules")) {
534 const char *value;
535 if (!git_config_get_value("push.recursesubmodules", &value))
536 recurse_submodules = parse_push_recurse_submodules_arg(k, value);
537 } else if (!strcmp(k, "submodule.recurse")) {
538 int val = git_config_bool(k, v) ?
539 RECURSE_SUBMODULES_ON_DEMAND : RECURSE_SUBMODULES_OFF;
540 recurse_submodules = val;
541 } else if (!strcmp(k, "push.pushoption")) {
542 if (!v)
543 return config_error_nonbool(k);
544 else
545 if (!*v)
546 string_list_clear(&push_options_config, 0);
547 else
548 string_list_append(&push_options_config, v);
549 return 0;
550 } else if (!strcmp(k, "color.push")) {
551 push_use_color = git_config_colorbool(k, v);
552 return 0;
553 } else if (skip_prefix(k, "color.push.", &slot_name)) {
554 int slot = parse_push_color_slot(slot_name);
555 if (slot < 0)
556 return 0;
557 if (!v)
558 return config_error_nonbool(k);
559 return color_parse(v, push_colors[slot]);
560 }
561
562 return git_default_config(k, v, NULL);
563}
564
565int cmd_push(int argc, const char **argv, const char *prefix)
566{
567 int flags = 0;
568 int tags = 0;
569 int push_cert = -1;
570 int rc;
571 const char *repo = NULL; /* default repository */
572 struct string_list push_options_cmdline = STRING_LIST_INIT_DUP;
573 struct string_list *push_options;
574 const struct string_list_item *item;
575
576 struct option options[] = {
577 OPT__VERBOSITY(&verbosity),
578 OPT_STRING( 0 , "repo", &repo, N_("repository"), N_("repository")),
579 OPT_BIT( 0 , "all", &flags, N_("push all refs"), TRANSPORT_PUSH_ALL),
580 OPT_BIT( 0 , "mirror", &flags, N_("mirror all refs"),
581 (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),
582 OPT_BOOL('d', "delete", &deleterefs, N_("delete refs")),
583 OPT_BOOL( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")),
584 OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN),
585 OPT_BIT( 0, "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN),
586 OPT_BIT('f', "force", &flags, N_("force updates"), TRANSPORT_PUSH_FORCE),
587 { OPTION_CALLBACK,
588 0, CAS_OPT_NAME, &cas, N_("refname>:<expect"),
589 N_("require old value of ref to be at this value"),
590 PARSE_OPT_OPTARG, parseopt_push_cas_option },
591 { OPTION_CALLBACK, 0, "recurse-submodules", &recurse_submodules, "check|on-demand|no",
592 N_("control recursive pushing of submodules"),
593 PARSE_OPT_OPTARG, option_parse_recurse_submodules },
594 OPT_BOOL_F( 0 , "thin", &thin, N_("use thin pack"), PARSE_OPT_NOCOMPLETE),
595 OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", N_("receive pack program")),
596 OPT_STRING( 0 , "exec", &receivepack, "receive-pack", N_("receive pack program")),
597 OPT_BIT('u', "set-upstream", &flags, N_("set upstream for git pull/status"),
598 TRANSPORT_PUSH_SET_UPSTREAM),
599 OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
600 OPT_BIT(0, "prune", &flags, N_("prune locally removed refs"),
601 TRANSPORT_PUSH_PRUNE),
602 OPT_BIT(0, "no-verify", &flags, N_("bypass pre-push hook"), TRANSPORT_PUSH_NO_HOOK),
603 OPT_BIT(0, "follow-tags", &flags, N_("push missing but relevant tags"),
604 TRANSPORT_PUSH_FOLLOW_TAGS),
605 { OPTION_CALLBACK,
606 0, "signed", &push_cert, "yes|no|if-asked", N_("GPG sign the push"),
607 PARSE_OPT_OPTARG, option_parse_push_signed },
608 OPT_BIT(0, "atomic", &flags, N_("request atomic transaction on remote side"), TRANSPORT_PUSH_ATOMIC),
609 OPT_STRING_LIST('o', "push-option", &push_options_cmdline, N_("server-specific"), N_("option to transmit")),
610 OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"),
611 TRANSPORT_FAMILY_IPV4),
612 OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
613 TRANSPORT_FAMILY_IPV6),
614 OPT_END()
615 };
616
617 packet_trace_identity("push");
618 git_config(git_push_config, &flags);
619 argc = parse_options(argc, argv, prefix, options, push_usage, 0);
620 push_options = (push_options_cmdline.nr
621 ? &push_options_cmdline
622 : &push_options_config);
623 set_push_cert_flags(&flags, push_cert);
624
625 if (deleterefs && (tags || (flags & (TRANSPORT_PUSH_ALL | TRANSPORT_PUSH_MIRROR))))
626 die(_("--delete is incompatible with --all, --mirror and --tags"));
627 if (deleterefs && argc < 2)
628 die(_("--delete doesn't make sense without any refs"));
629
630 if (recurse_submodules == RECURSE_SUBMODULES_CHECK)
631 flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK;
632 else if (recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)
633 flags |= TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND;
634 else if (recurse_submodules == RECURSE_SUBMODULES_ONLY)
635 flags |= TRANSPORT_RECURSE_SUBMODULES_ONLY;
636
637 if (tags)
638 add_refspec("refs/tags/*");
639
640 if (argc > 0) {
641 repo = argv[0];
642 set_refspecs(argv + 1, argc - 1, repo);
643 }
644
645 for_each_string_list_item(item, push_options)
646 if (strchr(item->string, '\n'))
647 die(_("push options must not have new line characters"));
648
649 rc = do_push(repo, flags, push_options);
650 string_list_clear(&push_options_cmdline, 0);
651 string_list_clear(&push_options_config, 0);
652 if (rc == -1)
653 usage_with_options(push_usage, options);
654 else
655 return rc;
656}