git

Форк
0
/
push.c 
671 строка · 20.7 Кб
1
/*
2
 * "git push"
3
 */
4
#include "builtin.h"
5
#include "advice.h"
6
#include "branch.h"
7
#include "config.h"
8
#include "environment.h"
9
#include "gettext.h"
10
#include "refspec.h"
11
#include "run-command.h"
12
#include "remote.h"
13
#include "transport.h"
14
#include "parse-options.h"
15
#include "pkt-line.h"
16
#include "repository.h"
17
#include "submodule.h"
18
#include "submodule-config.h"
19
#include "send-pack.h"
20
#include "trace2.h"
21
#include "color.h"
22

23
static const char * const push_usage[] = {
24
	N_("git push [<options>] [<repository> [<refspec>...]]"),
25
	NULL,
26
};
27

28
static int push_use_color = -1;
29
static char push_colors[][COLOR_MAXLEN] = {
30
	GIT_COLOR_RESET,
31
	GIT_COLOR_RED,	/* ERROR */
32
};
33

34
enum color_push {
35
	PUSH_COLOR_RESET = 0,
36
	PUSH_COLOR_ERROR = 1
37
};
38

39
static int parse_push_color_slot(const char *slot)
40
{
41
	if (!strcasecmp(slot, "reset"))
42
		return PUSH_COLOR_RESET;
43
	if (!strcasecmp(slot, "error"))
44
		return PUSH_COLOR_ERROR;
45
	return -1;
46
}
47

48
static const char *push_get_color(enum color_push ix)
49
{
50
	if (want_color_stderr(push_use_color))
51
		return push_colors[ix];
52
	return "";
53
}
54

55
static int thin = 1;
56
static int deleterefs;
57
static const char *receivepack;
58
static int verbosity;
59
static int progress = -1;
60
static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
61
static enum transport_family family;
62

63
static struct push_cas_option cas;
64

65
static struct refspec rs = REFSPEC_INIT_PUSH;
66

67
static struct string_list push_options_config = STRING_LIST_INIT_DUP;
68

69
static void refspec_append_mapped(struct refspec *refspec, const char *ref,
70
				  struct remote *remote, struct ref *matched)
71
{
72
	const char *branch_name;
73

74
	if (remote->push.nr) {
75
		struct refspec_item query;
76
		memset(&query, 0, sizeof(struct refspec_item));
77
		query.src = matched->name;
78
		if (!query_refspecs(&remote->push, &query) && query.dst) {
79
			refspec_appendf(refspec, "%s%s:%s",
80
					query.force ? "+" : "",
81
					query.src, query.dst);
82
			return;
83
		}
84
	}
85

86
	if (push_default == PUSH_DEFAULT_UPSTREAM &&
87
	    skip_prefix(matched->name, "refs/heads/", &branch_name)) {
88
		struct branch *branch = branch_get(branch_name);
89
		if (branch->merge_nr == 1 && branch->merge[0]->src) {
90
			refspec_appendf(refspec, "%s:%s",
91
					ref, branch->merge[0]->src);
92
			return;
93
		}
94
	}
95

96
	refspec_append(refspec, ref);
97
}
98

99
static void set_refspecs(const char **refs, int nr, struct remote *remote)
100
{
101
	struct ref *local_refs = NULL;
102
	int i;
103

104
	for (i = 0; i < nr; i++) {
105
		const char *ref = refs[i];
106
		if (!strcmp("tag", ref)) {
107
			if (nr <= ++i)
108
				die(_("tag shorthand without <tag>"));
109
			ref = refs[i];
110
			if (deleterefs)
111
				refspec_appendf(&rs, ":refs/tags/%s", ref);
112
			else
113
				refspec_appendf(&rs, "refs/tags/%s", ref);
114
		} else if (deleterefs) {
115
			if (strchr(ref, ':') || !*ref)
116
				die(_("--delete only accepts plain target ref names"));
117
			refspec_appendf(&rs, ":%s", ref);
118
		} else if (!strchr(ref, ':')) {
119
			struct ref *matched = NULL;
120

121
			/* lazily grab local_refs */
122
			if (!local_refs)
123
				local_refs = get_local_heads();
124

125
			/* Does "ref" uniquely name our ref? */
126
			if (count_refspec_match(ref, local_refs, &matched) != 1)
127
				refspec_append(&rs, ref);
128
			else
129
				refspec_append_mapped(&rs, ref, remote, matched);
130
		} else
131
			refspec_append(&rs, ref);
132
	}
133
	free_refs(local_refs);
134
}
135

136
static NORETURN void die_push_simple(struct branch *branch,
137
				     struct remote *remote)
138
{
139
	/*
140
	 * There's no point in using shorten_unambiguous_ref here,
141
	 * as the ambiguity would be on the remote side, not what
142
	 * we have locally. Plus, this is supposed to be the simple
143
	 * mode. If the user is doing something crazy like setting
144
	 * upstream to a non-branch, we should probably be showing
145
	 * them the big ugly fully qualified ref.
146
	 */
147
	const char *advice_pushdefault_maybe = "";
148
	const char *advice_automergesimple_maybe = "";
149
	const char *short_upstream = branch->merge[0]->src;
150

151
	skip_prefix(short_upstream, "refs/heads/", &short_upstream);
152

153
	/*
154
	 * Don't show advice for people who explicitly set
155
	 * push.default.
156
	 */
157
	if (push_default == PUSH_DEFAULT_UNSPECIFIED)
158
		advice_pushdefault_maybe = _("\n"
159
				 "To choose either option permanently, "
160
				 "see push.default in 'git help config'.\n");
161
	if (git_branch_track != BRANCH_TRACK_SIMPLE)
162
		advice_automergesimple_maybe = _("\n"
163
				 "To avoid automatically configuring "
164
				 "an upstream branch when its name\n"
165
				 "won't match the local branch, see option "
166
				 "'simple' of branch.autoSetupMerge\n"
167
				 "in 'git help config'.\n");
168
	die(_("The upstream branch of your current branch does not match\n"
169
	      "the name of your current branch.  To push to the upstream branch\n"
170
	      "on the remote, use\n"
171
	      "\n"
172
	      "    git push %s HEAD:%s\n"
173
	      "\n"
174
	      "To push to the branch of the same name on the remote, use\n"
175
	      "\n"
176
	      "    git push %s HEAD\n"
177
	      "%s%s"),
178
	    remote->name, short_upstream,
179
	    remote->name, advice_pushdefault_maybe,
180
	    advice_automergesimple_maybe);
181
}
182

183
static const char message_detached_head_die[] =
184
	N_("You are not currently on a branch.\n"
185
	   "To push the history leading to the current (detached HEAD)\n"
186
	   "state now, use\n"
187
	   "\n"
188
	   "    git push %s HEAD:<name-of-remote-branch>\n");
189

190
static const char *get_upstream_ref(int flags, struct branch *branch, const char *remote_name)
191
{
192
	if (branch->merge_nr == 0 && (flags & TRANSPORT_PUSH_AUTO_UPSTREAM)) {
193
		/* if missing, assume same; set_upstream will be defined later */
194
		return branch->refname;
195
	}
196

197
	if (!branch->merge_nr || !branch->merge || !branch->remote_name) {
198
		const char *advice_autosetup_maybe = "";
199
		if (!(flags & TRANSPORT_PUSH_AUTO_UPSTREAM)) {
200
			advice_autosetup_maybe = _("\n"
201
					   "To have this happen automatically for "
202
					   "branches without a tracking\n"
203
					   "upstream, see 'push.autoSetupRemote' "
204
					   "in 'git help config'.\n");
205
		}
206
		die(_("The current branch %s has no upstream branch.\n"
207
		    "To push the current branch and set the remote as upstream, use\n"
208
		    "\n"
209
		    "    git push --set-upstream %s %s\n"
210
		    "%s"),
211
		    branch->name,
212
		    remote_name,
213
		    branch->name,
214
		    advice_autosetup_maybe);
215
	}
216
	if (branch->merge_nr != 1)
217
		die(_("The current branch %s has multiple upstream branches, "
218
		    "refusing to push."), branch->name);
219

220
	return branch->merge[0]->src;
221
}
222

223
static void setup_default_push_refspecs(int *flags, struct remote *remote)
224
{
225
	struct branch *branch;
226
	const char *dst;
227
	int same_remote;
228

229
	switch (push_default) {
230
	case PUSH_DEFAULT_MATCHING:
231
		refspec_append(&rs, ":");
232
		return;
233

234
	case PUSH_DEFAULT_NOTHING:
235
		die(_("You didn't specify any refspecs to push, and "
236
		    "push.default is \"nothing\"."));
237
		return;
238
	default:
239
		break;
240
	}
241

242
	branch = branch_get(NULL);
243
	if (!branch)
244
		die(_(message_detached_head_die), remote->name);
245

246
	dst = branch->refname;
247
	same_remote = !strcmp(remote->name, remote_for_branch(branch, NULL));
248

249
	switch (push_default) {
250
	default:
251
	case PUSH_DEFAULT_UNSPECIFIED:
252
	case PUSH_DEFAULT_SIMPLE:
253
		if (!same_remote)
254
			break;
255
		if (strcmp(branch->refname, get_upstream_ref(*flags, branch, remote->name)))
256
			die_push_simple(branch, remote);
257
		break;
258

259
	case PUSH_DEFAULT_UPSTREAM:
260
		if (!same_remote)
261
			die(_("You are pushing to remote '%s', which is not the upstream of\n"
262
			      "your current branch '%s', without telling me what to push\n"
263
			      "to update which remote branch."),
264
			    remote->name, branch->name);
265
		dst = get_upstream_ref(*flags, branch, remote->name);
266
		break;
267

268
	case PUSH_DEFAULT_CURRENT:
269
		break;
270
	}
271

272
	/*
273
	 * this is a default push - if auto-upstream is enabled and there is
274
	 * no upstream defined, then set it (with options 'simple', 'upstream',
275
	 * and 'current').
276
	 */
277
	if ((*flags & TRANSPORT_PUSH_AUTO_UPSTREAM) && branch->merge_nr == 0)
278
		*flags |= TRANSPORT_PUSH_SET_UPSTREAM;
279

280
	refspec_appendf(&rs, "%s:%s", branch->refname, dst);
281
}
282

283
static 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. If you want to integrate the remote changes,\n"
286
	   "use 'git pull' before pushing again.\n"
287
	   "See the 'Note about fast-forwards' in 'git push --help' for details.");
288

289
static const char message_advice_checkout_pull_push[] =
290
	N_("Updates were rejected because a pushed branch tip is behind its remote\n"
291
	   "counterpart. If you want to integrate the remote changes, use 'git pull'\n"
292
	   "before pushing again.\n"
293
	   "See the 'Note about fast-forwards' in 'git push --help' for details.");
294

295
static const char message_advice_ref_fetch_first[] =
296
	N_("Updates were rejected because the remote contains work that you do not\n"
297
	   "have locally. This is usually caused by another repository pushing to\n"
298
	   "the same ref. If you want to integrate the remote changes, use\n"
299
	   "'git pull' before pushing again.\n"
300
	   "See the 'Note about fast-forwards' in 'git push --help' for details.");
301

302
static const char message_advice_ref_already_exists[] =
303
	N_("Updates were rejected because the tag already exists in the remote.");
304

305
static 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

310
static const char message_advice_ref_needs_update[] =
311
	N_("Updates were rejected because the tip of the remote-tracking branch has\n"
312
	   "been updated since the last checkout. If you want to integrate the\n"
313
	   "remote changes, use 'git pull' before pushing again.\n"
314
	   "See the 'Note about fast-forwards' in 'git push --help' for details.");
315

316
static void advise_pull_before_push(void)
317
{
318
	if (!advice_enabled(ADVICE_PUSH_NON_FF_CURRENT) || !advice_enabled(ADVICE_PUSH_UPDATE_REJECTED))
319
		return;
320
	advise(_(message_advice_pull_before_push));
321
}
322

323
static void advise_checkout_pull_push(void)
324
{
325
	if (!advice_enabled(ADVICE_PUSH_NON_FF_MATCHING) || !advice_enabled(ADVICE_PUSH_UPDATE_REJECTED))
326
		return;
327
	advise(_(message_advice_checkout_pull_push));
328
}
329

330
static void advise_ref_already_exists(void)
331
{
332
	if (!advice_enabled(ADVICE_PUSH_ALREADY_EXISTS) || !advice_enabled(ADVICE_PUSH_UPDATE_REJECTED))
333
		return;
334
	advise(_(message_advice_ref_already_exists));
335
}
336

337
static void advise_ref_fetch_first(void)
338
{
339
	if (!advice_enabled(ADVICE_PUSH_FETCH_FIRST) || !advice_enabled(ADVICE_PUSH_UPDATE_REJECTED))
340
		return;
341
	advise(_(message_advice_ref_fetch_first));
342
}
343

344
static void advise_ref_needs_force(void)
345
{
346
	if (!advice_enabled(ADVICE_PUSH_NEEDS_FORCE) || !advice_enabled(ADVICE_PUSH_UPDATE_REJECTED))
347
		return;
348
	advise(_(message_advice_ref_needs_force));
349
}
350

351
static void advise_ref_needs_update(void)
352
{
353
	if (!advice_enabled(ADVICE_PUSH_REF_NEEDS_UPDATE) || !advice_enabled(ADVICE_PUSH_UPDATE_REJECTED))
354
		return;
355
	advise(_(message_advice_ref_needs_update));
356
}
357

358
static int push_with_options(struct transport *transport, struct refspec *rs,
359
			     int flags)
360
{
361
	int err;
362
	unsigned int reject_reasons;
363
	char *anon_url = transport_anonymize_url(transport->url);
364

365
	transport_set_verbosity(transport, verbosity, progress);
366
	transport->family = family;
367

368
	if (receivepack)
369
		transport_set_option(transport,
370
				     TRANS_OPT_RECEIVEPACK, receivepack);
371
	transport_set_option(transport, TRANS_OPT_THIN, thin ? "yes" : NULL);
372

373
	if (!is_empty_cas(&cas)) {
374
		if (!transport->smart_options)
375
			die("underlying transport does not support --%s option",
376
			    "force-with-lease");
377
		transport->smart_options->cas = &cas;
378
	}
379

380
	if (verbosity > 0)
381
		fprintf(stderr, _("Pushing to %s\n"), anon_url);
382
	trace2_region_enter("push", "transport_push", the_repository);
383
	err = transport_push(the_repository, transport,
384
			     rs, flags, &reject_reasons);
385
	trace2_region_leave("push", "transport_push", the_repository);
386
	if (err != 0) {
387
		fprintf(stderr, "%s", push_get_color(PUSH_COLOR_ERROR));
388
		error(_("failed to push some refs to '%s'"), anon_url);
389
		fprintf(stderr, "%s", push_get_color(PUSH_COLOR_RESET));
390
	}
391

392
	err |= transport_disconnect(transport);
393
	free(anon_url);
394
	if (!err)
395
		return 0;
396

397
	if (reject_reasons & REJECT_NON_FF_HEAD) {
398
		advise_pull_before_push();
399
	} else if (reject_reasons & REJECT_NON_FF_OTHER) {
400
		advise_checkout_pull_push();
401
	} else if (reject_reasons & REJECT_ALREADY_EXISTS) {
402
		advise_ref_already_exists();
403
	} else if (reject_reasons & REJECT_FETCH_FIRST) {
404
		advise_ref_fetch_first();
405
	} else if (reject_reasons & REJECT_NEEDS_FORCE) {
406
		advise_ref_needs_force();
407
	} else if (reject_reasons & REJECT_REF_NEEDS_UPDATE) {
408
		advise_ref_needs_update();
409
	}
410

411
	return 1;
412
}
413

414
static int do_push(int flags,
415
		   const struct string_list *push_options,
416
		   struct remote *remote)
417
{
418
	int i, errs;
419
	struct strvec *url;
420
	struct refspec *push_refspec = &rs;
421

422
	if (push_options->nr)
423
		flags |= TRANSPORT_PUSH_OPTIONS;
424

425
	if (!push_refspec->nr && !(flags & TRANSPORT_PUSH_ALL)) {
426
		if (remote->push.nr) {
427
			push_refspec = &remote->push;
428
		} else if (!(flags & TRANSPORT_PUSH_MIRROR))
429
			setup_default_push_refspecs(&flags, remote);
430
	}
431
	errs = 0;
432
	url = push_url_of_remote(remote);
433
	for (i = 0; i < url->nr; i++) {
434
		struct transport *transport =
435
			transport_get(remote, url->v[i]);
436
		if (flags & TRANSPORT_PUSH_OPTIONS)
437
			transport->push_options = push_options;
438
		if (push_with_options(transport, push_refspec, flags))
439
			errs++;
440
	}
441
	return !!errs;
442
}
443

444
static int option_parse_recurse_submodules(const struct option *opt,
445
				   const char *arg, int unset)
446
{
447
	int *recurse_submodules = opt->value;
448

449
	if (unset)
450
		*recurse_submodules = RECURSE_SUBMODULES_OFF;
451
	else {
452
		if (!strcmp(arg, "only-is-on-demand")) {
453
			if (*recurse_submodules == RECURSE_SUBMODULES_ONLY) {
454
				warning(_("recursing into submodule with push.recurseSubmodules=only; using on-demand instead"));
455
				*recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND;
456
			}
457
		} else {
458
			*recurse_submodules = parse_push_recurse_submodules_arg(opt->long_name, arg);
459
		}
460
	}
461

462
	return 0;
463
}
464

465
static void set_push_cert_flags(int *flags, int v)
466
{
467
	switch (v) {
468
	case SEND_PACK_PUSH_CERT_NEVER:
469
		*flags &= ~(TRANSPORT_PUSH_CERT_ALWAYS | TRANSPORT_PUSH_CERT_IF_ASKED);
470
		break;
471
	case SEND_PACK_PUSH_CERT_ALWAYS:
472
		*flags |= TRANSPORT_PUSH_CERT_ALWAYS;
473
		*flags &= ~TRANSPORT_PUSH_CERT_IF_ASKED;
474
		break;
475
	case SEND_PACK_PUSH_CERT_IF_ASKED:
476
		*flags |= TRANSPORT_PUSH_CERT_IF_ASKED;
477
		*flags &= ~TRANSPORT_PUSH_CERT_ALWAYS;
478
		break;
479
	}
480
}
481

482

483
static int git_push_config(const char *k, const char *v,
484
			   const struct config_context *ctx, void *cb)
485
{
486
	const char *slot_name;
487
	int *flags = cb;
488

489
	if (!strcmp(k, "push.followtags")) {
490
		if (git_config_bool(k, v))
491
			*flags |= TRANSPORT_PUSH_FOLLOW_TAGS;
492
		else
493
			*flags &= ~TRANSPORT_PUSH_FOLLOW_TAGS;
494
		return 0;
495
	} else if (!strcmp(k, "push.autosetupremote")) {
496
		if (git_config_bool(k, v))
497
			*flags |= TRANSPORT_PUSH_AUTO_UPSTREAM;
498
		return 0;
499
	} else if (!strcmp(k, "push.gpgsign")) {
500
		switch (git_parse_maybe_bool(v)) {
501
		case 0:
502
			set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_NEVER);
503
			break;
504
		case 1:
505
			set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_ALWAYS);
506
			break;
507
		default:
508
			if (!strcasecmp(v, "if-asked"))
509
				set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_IF_ASKED);
510
			else
511
				return error(_("invalid value for '%s'"), k);
512
		}
513
	} else if (!strcmp(k, "push.recursesubmodules")) {
514
		recurse_submodules = parse_push_recurse_submodules_arg(k, v);
515
	} else if (!strcmp(k, "submodule.recurse")) {
516
		int val = git_config_bool(k, v) ?
517
			RECURSE_SUBMODULES_ON_DEMAND : RECURSE_SUBMODULES_OFF;
518
		recurse_submodules = val;
519
	} else if (!strcmp(k, "push.pushoption")) {
520
		if (!v)
521
			return config_error_nonbool(k);
522
		else
523
			if (!*v)
524
				string_list_clear(&push_options_config, 0);
525
			else
526
				string_list_append(&push_options_config, v);
527
		return 0;
528
	} else if (!strcmp(k, "color.push")) {
529
		push_use_color = git_config_colorbool(k, v);
530
		return 0;
531
	} else if (skip_prefix(k, "color.push.", &slot_name)) {
532
		int slot = parse_push_color_slot(slot_name);
533
		if (slot < 0)
534
			return 0;
535
		if (!v)
536
			return config_error_nonbool(k);
537
		return color_parse(v, push_colors[slot]);
538
	} else if (!strcmp(k, "push.useforceifincludes")) {
539
		if (git_config_bool(k, v))
540
			*flags |= TRANSPORT_PUSH_FORCE_IF_INCLUDES;
541
		else
542
			*flags &= ~TRANSPORT_PUSH_FORCE_IF_INCLUDES;
543
		return 0;
544
	}
545

546
	return git_default_config(k, v, ctx, NULL);
547
}
548

549
int cmd_push(int argc, const char **argv, const char *prefix)
550
{
551
	int flags = 0;
552
	int tags = 0;
553
	int push_cert = -1;
554
	int rc;
555
	const char *repo = NULL;	/* default repository */
556
	struct string_list push_options_cmdline = STRING_LIST_INIT_DUP;
557
	struct string_list *push_options;
558
	const struct string_list_item *item;
559
	struct remote *remote;
560

561
	struct option options[] = {
562
		OPT__VERBOSITY(&verbosity),
563
		OPT_STRING( 0 , "repo", &repo, N_("repository"), N_("repository")),
564
		OPT_BIT( 0 , "all", &flags, N_("push all branches"), TRANSPORT_PUSH_ALL),
565
		OPT_ALIAS( 0 , "branches", "all"),
566
		OPT_BIT( 0 , "mirror", &flags, N_("mirror all refs"),
567
			    (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),
568
		OPT_BOOL('d', "delete", &deleterefs, N_("delete refs")),
569
		OPT_BOOL( 0 , "tags", &tags, N_("push tags (can't be used with --all or --branches or --mirror)")),
570
		OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN),
571
		OPT_BIT( 0,  "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN),
572
		OPT_BIT('f', "force", &flags, N_("force updates"), TRANSPORT_PUSH_FORCE),
573
		OPT_CALLBACK_F(0, "force-with-lease", &cas, N_("<refname>:<expect>"),
574
			       N_("require old value of ref to be at this value"),
575
			       PARSE_OPT_OPTARG | PARSE_OPT_LITERAL_ARGHELP, parseopt_push_cas_option),
576
		OPT_BIT(0, TRANS_OPT_FORCE_IF_INCLUDES, &flags,
577
			N_("require remote updates to be integrated locally"),
578
			TRANSPORT_PUSH_FORCE_IF_INCLUDES),
579
		OPT_CALLBACK(0, "recurse-submodules", &recurse_submodules, "(check|on-demand|no)",
580
			     N_("control recursive pushing of submodules"), option_parse_recurse_submodules),
581
		OPT_BOOL_F( 0 , "thin", &thin, N_("use thin pack"), PARSE_OPT_NOCOMPLETE),
582
		OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", N_("receive pack program")),
583
		OPT_STRING( 0 , "exec", &receivepack, "receive-pack", N_("receive pack program")),
584
		OPT_BIT('u', "set-upstream", &flags, N_("set upstream for git pull/status"),
585
			TRANSPORT_PUSH_SET_UPSTREAM),
586
		OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
587
		OPT_BIT(0, "prune", &flags, N_("prune locally removed refs"),
588
			TRANSPORT_PUSH_PRUNE),
589
		OPT_BIT(0, "no-verify", &flags, N_("bypass pre-push hook"), TRANSPORT_PUSH_NO_HOOK),
590
		OPT_BIT(0, "follow-tags", &flags, N_("push missing but relevant tags"),
591
			TRANSPORT_PUSH_FOLLOW_TAGS),
592
		OPT_CALLBACK_F(0, "signed", &push_cert, "(yes|no|if-asked)", N_("GPG sign the push"),
593
				PARSE_OPT_OPTARG, option_parse_push_signed),
594
		OPT_BIT(0, "atomic", &flags, N_("request atomic transaction on remote side"), TRANSPORT_PUSH_ATOMIC),
595
		OPT_STRING_LIST('o', "push-option", &push_options_cmdline, N_("server-specific"), N_("option to transmit")),
596
		OPT_IPVERSION(&family),
597
		OPT_END()
598
	};
599

600
	packet_trace_identity("push");
601
	git_config(git_push_config, &flags);
602
	argc = parse_options(argc, argv, prefix, options, push_usage, 0);
603
	push_options = (push_options_cmdline.nr
604
		? &push_options_cmdline
605
		: &push_options_config);
606
	set_push_cert_flags(&flags, push_cert);
607

608
	die_for_incompatible_opt4(deleterefs, "--delete",
609
				  tags, "--tags",
610
				  flags & TRANSPORT_PUSH_ALL, "--all/--branches",
611
				  flags & TRANSPORT_PUSH_MIRROR, "--mirror");
612
	if (deleterefs && argc < 2)
613
		die(_("--delete doesn't make sense without any refs"));
614

615
	if (recurse_submodules == RECURSE_SUBMODULES_CHECK)
616
		flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK;
617
	else if (recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)
618
		flags |= TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND;
619
	else if (recurse_submodules == RECURSE_SUBMODULES_ONLY)
620
		flags |= TRANSPORT_RECURSE_SUBMODULES_ONLY;
621

622
	if (tags)
623
		refspec_append(&rs, "refs/tags/*");
624

625
	if (argc > 0)
626
		repo = argv[0];
627

628
	remote = pushremote_get(repo);
629
	if (!remote) {
630
		if (repo)
631
			die(_("bad repository '%s'"), repo);
632
		die(_("No configured push destination.\n"
633
		    "Either specify the URL from the command-line or configure a remote repository using\n"
634
		    "\n"
635
		    "    git remote add <name> <url>\n"
636
		    "\n"
637
		    "and then push using the remote name\n"
638
		    "\n"
639
		    "    git push <name>\n"));
640
	}
641

642
	if (argc > 0)
643
		set_refspecs(argv + 1, argc - 1, remote);
644

645
	if (remote->mirror)
646
		flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
647

648
	if (flags & TRANSPORT_PUSH_ALL) {
649
		if (argc >= 2)
650
			die(_("--all can't be combined with refspecs"));
651
	}
652
	if (flags & TRANSPORT_PUSH_MIRROR) {
653
		if (argc >= 2)
654
			die(_("--mirror can't be combined with refspecs"));
655
	}
656

657
	if (!is_empty_cas(&cas) && (flags & TRANSPORT_PUSH_FORCE_IF_INCLUDES))
658
		cas.use_force_if_includes = 1;
659

660
	for_each_string_list_item(item, push_options)
661
		if (strchr(item->string, '\n'))
662
			die(_("push options must not have new line characters"));
663

664
	rc = do_push(flags, push_options, remote);
665
	string_list_clear(&push_options_cmdline, 0);
666
	string_list_clear(&push_options_config, 0);
667
	if (rc == -1)
668
		usage_with_options(push_usage, options);
669
	else
670
		return rc;
671
}
672

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.