git

Форк
0
/
transport-helper.c 
1656 строк · 42.6 Кб
1
#define USE_THE_REPOSITORY_VARIABLE
2

3
#include "git-compat-util.h"
4
#include "transport.h"
5
#include "quote.h"
6
#include "run-command.h"
7
#include "commit.h"
8
#include "environment.h"
9
#include "gettext.h"
10
#include "hex.h"
11
#include "object-name.h"
12
#include "repository.h"
13
#include "remote.h"
14
#include "string-list.h"
15
#include "thread-utils.h"
16
#include "sigchain.h"
17
#include "strvec.h"
18
#include "refs.h"
19
#include "refspec.h"
20
#include "transport-internal.h"
21
#include "protocol.h"
22
#include "packfile.h"
23

24
static int debug;
25

26
struct helper_data {
27
	char *name;
28
	struct child_process *helper;
29
	FILE *out;
30
	unsigned fetch : 1,
31
		import : 1,
32
		bidi_import : 1,
33
		export : 1,
34
		option : 1,
35
		push : 1,
36
		connect : 1,
37
		stateless_connect : 1,
38
		signed_tags : 1,
39
		check_connectivity : 1,
40
		no_disconnect_req : 1,
41
		no_private_update : 1,
42
		object_format : 1;
43

44
	/*
45
	 * As an optimization, the transport code may invoke fetch before
46
	 * get_refs_list. If this happens, and if the transport helper doesn't
47
	 * support connect or stateless_connect, we need to invoke
48
	 * get_refs_list ourselves if we haven't already done so. Keep track of
49
	 * whether we have invoked get_refs_list.
50
	 */
51
	unsigned get_refs_list_called : 1;
52

53
	char *export_marks;
54
	char *import_marks;
55
	/* These go from remote name (as in "list") to private name */
56
	struct refspec rs;
57
	/* Transport options for fetch-pack/send-pack (should one of
58
	 * those be invoked).
59
	 */
60
	struct git_transport_options transport_options;
61
};
62

63
static void sendline(struct helper_data *helper, struct strbuf *buffer)
64
{
65
	if (debug)
66
		fprintf(stderr, "Debug: Remote helper: -> %s", buffer->buf);
67
	if (write_in_full(helper->helper->in, buffer->buf, buffer->len) < 0)
68
		die_errno(_("full write to remote helper failed"));
69
}
70

71
static int recvline_fh(FILE *helper, struct strbuf *buffer)
72
{
73
	strbuf_reset(buffer);
74
	if (debug)
75
		fprintf(stderr, "Debug: Remote helper: Waiting...\n");
76
	if (strbuf_getline(buffer, helper) == EOF) {
77
		if (debug)
78
			fprintf(stderr, "Debug: Remote helper quit.\n");
79
		return 1;
80
	}
81

82
	if (debug)
83
		fprintf(stderr, "Debug: Remote helper: <- %s\n", buffer->buf);
84
	return 0;
85
}
86

87
static int recvline(struct helper_data *helper, struct strbuf *buffer)
88
{
89
	return recvline_fh(helper->out, buffer);
90
}
91

92
static void write_constant(int fd, const char *str)
93
{
94
	if (debug)
95
		fprintf(stderr, "Debug: Remote helper: -> %s", str);
96
	if (write_in_full(fd, str, strlen(str)) < 0)
97
		die_errno(_("full write to remote helper failed"));
98
}
99

100
static const char *remove_ext_force(const char *url)
101
{
102
	if (url) {
103
		const char *colon = strchr(url, ':');
104
		if (colon && colon[1] == ':')
105
			return colon + 2;
106
	}
107
	return url;
108
}
109

110
static void do_take_over(struct transport *transport)
111
{
112
	struct helper_data *data;
113
	data = (struct helper_data *)transport->data;
114
	transport_take_over(transport, data->helper);
115
	fclose(data->out);
116
	free(data->name);
117
	free(data);
118
}
119

120
static void standard_options(struct transport *t);
121

122
static struct child_process *get_helper(struct transport *transport)
123
{
124
	struct helper_data *data = transport->data;
125
	struct strbuf buf = STRBUF_INIT;
126
	struct child_process *helper;
127
	int duped;
128
	int code;
129

130
	if (data->helper)
131
		return data->helper;
132

133
	helper = xmalloc(sizeof(*helper));
134
	child_process_init(helper);
135
	helper->in = -1;
136
	helper->out = -1;
137
	helper->err = 0;
138
	strvec_pushf(&helper->args, "remote-%s", data->name);
139
	strvec_push(&helper->args, transport->remote->name);
140
	strvec_push(&helper->args, remove_ext_force(transport->url));
141
	helper->git_cmd = 1;
142
	helper->silent_exec_failure = 1;
143

144
	if (have_git_dir())
145
		strvec_pushf(&helper->env, "%s=%s",
146
			     GIT_DIR_ENVIRONMENT, get_git_dir());
147

148
	helper->trace2_child_class = helper->args.v[0]; /* "remote-<name>" */
149

150
	code = start_command(helper);
151
	if (code < 0 && errno == ENOENT)
152
		die(_("unable to find remote helper for '%s'"), data->name);
153
	else if (code != 0)
154
		exit(code);
155

156
	data->helper = helper;
157
	data->no_disconnect_req = 0;
158
	refspec_init(&data->rs, REFSPEC_FETCH);
159

160
	/*
161
	 * Open the output as FILE* so strbuf_getline_*() family of
162
	 * functions can be used.
163
	 * Do this with duped fd because fclose() will close the fd,
164
	 * and stuff like taking over will require the fd to remain.
165
	 */
166
	duped = dup(helper->out);
167
	if (duped < 0)
168
		die_errno(_("can't dup helper output fd"));
169
	data->out = xfdopen(duped, "r");
170

171
	write_constant(helper->in, "capabilities\n");
172

173
	while (1) {
174
		const char *capname, *arg;
175
		int mandatory = 0;
176
		if (recvline(data, &buf))
177
			exit(128);
178

179
		if (!*buf.buf)
180
			break;
181

182
		if (*buf.buf == '*') {
183
			capname = buf.buf + 1;
184
			mandatory = 1;
185
		} else
186
			capname = buf.buf;
187

188
		if (debug)
189
			fprintf(stderr, "Debug: Got cap %s\n", capname);
190
		if (!strcmp(capname, "fetch"))
191
			data->fetch = 1;
192
		else if (!strcmp(capname, "option"))
193
			data->option = 1;
194
		else if (!strcmp(capname, "push"))
195
			data->push = 1;
196
		else if (!strcmp(capname, "import"))
197
			data->import = 1;
198
		else if (!strcmp(capname, "bidi-import"))
199
			data->bidi_import = 1;
200
		else if (!strcmp(capname, "export"))
201
			data->export = 1;
202
		else if (!strcmp(capname, "check-connectivity"))
203
			data->check_connectivity = 1;
204
		else if (skip_prefix(capname, "refspec ", &arg)) {
205
			refspec_append(&data->rs, arg);
206
		} else if (!strcmp(capname, "connect")) {
207
			data->connect = 1;
208
		} else if (!strcmp(capname, "stateless-connect")) {
209
			data->stateless_connect = 1;
210
		} else if (!strcmp(capname, "signed-tags")) {
211
			data->signed_tags = 1;
212
		} else if (skip_prefix(capname, "export-marks ", &arg)) {
213
			data->export_marks = xstrdup(arg);
214
		} else if (skip_prefix(capname, "import-marks ", &arg)) {
215
			data->import_marks = xstrdup(arg);
216
		} else if (starts_with(capname, "no-private-update")) {
217
			data->no_private_update = 1;
218
		} else if (starts_with(capname, "object-format")) {
219
			data->object_format = 1;
220
		} else if (mandatory) {
221
			die(_("unknown mandatory capability %s; this remote "
222
			      "helper probably needs newer version of Git"),
223
			    capname);
224
		}
225
	}
226
	if (!data->rs.nr && (data->import || data->bidi_import || data->export)) {
227
		warning(_("this remote helper should implement refspec capability"));
228
	}
229
	strbuf_release(&buf);
230
	if (debug)
231
		fprintf(stderr, "Debug: Capabilities complete.\n");
232
	standard_options(transport);
233
	return data->helper;
234
}
235

236
static int disconnect_helper(struct transport *transport)
237
{
238
	struct helper_data *data = transport->data;
239
	int res = 0;
240

241
	if (data->helper) {
242
		if (debug)
243
			fprintf(stderr, "Debug: Disconnecting.\n");
244
		if (!data->no_disconnect_req) {
245
			/*
246
			 * Ignore write errors; there's nothing we can do,
247
			 * since we're about to close the pipe anyway. And the
248
			 * most likely error is EPIPE due to the helper dying
249
			 * to report an error itself.
250
			 */
251
			sigchain_push(SIGPIPE, SIG_IGN);
252
			xwrite(data->helper->in, "\n", 1);
253
			sigchain_pop(SIGPIPE);
254
		}
255
		close(data->helper->in);
256
		close(data->helper->out);
257
		fclose(data->out);
258
		res = finish_command(data->helper);
259
		FREE_AND_NULL(data->name);
260
		FREE_AND_NULL(data->helper);
261
	}
262
	return res;
263
}
264

265
static const char *unsupported_options[] = {
266
	TRANS_OPT_UPLOADPACK,
267
	TRANS_OPT_RECEIVEPACK,
268
	TRANS_OPT_THIN,
269
	TRANS_OPT_KEEP
270
	};
271

272
static const char *boolean_options[] = {
273
	TRANS_OPT_THIN,
274
	TRANS_OPT_KEEP,
275
	TRANS_OPT_FOLLOWTAGS,
276
	TRANS_OPT_DEEPEN_RELATIVE
277
	};
278

279
static int strbuf_set_helper_option(struct helper_data *data,
280
				    struct strbuf *buf)
281
{
282
	int ret;
283

284
	sendline(data, buf);
285
	if (recvline(data, buf))
286
		exit(128);
287

288
	if (!strcmp(buf->buf, "ok"))
289
		ret = 0;
290
	else if (starts_with(buf->buf, "error"))
291
		ret = -1;
292
	else if (!strcmp(buf->buf, "unsupported"))
293
		ret = 1;
294
	else {
295
		warning(_("%s unexpectedly said: '%s'"), data->name, buf->buf);
296
		ret = 1;
297
	}
298
	return ret;
299
}
300

301
static int string_list_set_helper_option(struct helper_data *data,
302
					 const char *name,
303
					 struct string_list *list)
304
{
305
	struct strbuf buf = STRBUF_INIT;
306
	int i, ret = 0;
307

308
	for (i = 0; i < list->nr; i++) {
309
		strbuf_addf(&buf, "option %s ", name);
310
		quote_c_style(list->items[i].string, &buf, NULL, 0);
311
		strbuf_addch(&buf, '\n');
312

313
		if ((ret = strbuf_set_helper_option(data, &buf)))
314
			break;
315
		strbuf_reset(&buf);
316
	}
317
	strbuf_release(&buf);
318
	return ret;
319
}
320

321
static int set_helper_option(struct transport *transport,
322
			  const char *name, const char *value)
323
{
324
	struct helper_data *data = transport->data;
325
	struct strbuf buf = STRBUF_INIT;
326
	int i, ret, is_bool = 0;
327

328
	get_helper(transport);
329

330
	if (!data->option)
331
		return 1;
332

333
	if (!strcmp(name, "deepen-not"))
334
		return string_list_set_helper_option(data, name,
335
						     (struct string_list *)value);
336

337
	for (i = 0; i < ARRAY_SIZE(unsupported_options); i++) {
338
		if (!strcmp(name, unsupported_options[i]))
339
			return 1;
340
	}
341

342
	for (i = 0; i < ARRAY_SIZE(boolean_options); i++) {
343
		if (!strcmp(name, boolean_options[i])) {
344
			is_bool = 1;
345
			break;
346
		}
347
	}
348

349
	strbuf_addf(&buf, "option %s ", name);
350
	if (is_bool)
351
		strbuf_addstr(&buf, value ? "true" : "false");
352
	else
353
		quote_c_style(value, &buf, NULL, 0);
354
	strbuf_addch(&buf, '\n');
355

356
	ret = strbuf_set_helper_option(data, &buf);
357
	strbuf_release(&buf);
358
	return ret;
359
}
360

361
static void standard_options(struct transport *t)
362
{
363
	char buf[16];
364
	int v = t->verbose;
365

366
	set_helper_option(t, "progress", t->progress ? "true" : "false");
367

368
	xsnprintf(buf, sizeof(buf), "%d", v + 1);
369
	set_helper_option(t, "verbosity", buf);
370

371
	switch (t->family) {
372
	case TRANSPORT_FAMILY_ALL:
373
		/*
374
		 * this is already the default,
375
		 * do not break old remote helpers by setting "all" here
376
		 */
377
		break;
378
	case TRANSPORT_FAMILY_IPV4:
379
		set_helper_option(t, "family", "ipv4");
380
		break;
381
	case TRANSPORT_FAMILY_IPV6:
382
		set_helper_option(t, "family", "ipv6");
383
		break;
384
	}
385
}
386

387
static int release_helper(struct transport *transport)
388
{
389
	int res = 0;
390
	struct helper_data *data = transport->data;
391
	refspec_clear(&data->rs);
392
	res = disconnect_helper(transport);
393
	free(transport->data);
394
	return res;
395
}
396

397
static int fetch_with_fetch(struct transport *transport,
398
			    int nr_heads, struct ref **to_fetch)
399
{
400
	struct helper_data *data = transport->data;
401
	int i;
402
	struct strbuf buf = STRBUF_INIT;
403

404
	for (i = 0; i < nr_heads; i++) {
405
		const struct ref *posn = to_fetch[i];
406
		if (posn->status & REF_STATUS_UPTODATE)
407
			continue;
408

409
		strbuf_addf(&buf, "fetch %s %s\n",
410
			    oid_to_hex(&posn->old_oid),
411
			    posn->symref ? posn->symref : posn->name);
412
	}
413

414
	strbuf_addch(&buf, '\n');
415
	sendline(data, &buf);
416

417
	while (1) {
418
		const char *name;
419

420
		if (recvline(data, &buf))
421
			exit(128);
422

423
		if (skip_prefix(buf.buf, "lock ", &name)) {
424
			if (transport->pack_lockfiles.nr)
425
				warning(_("%s also locked %s"), data->name, name);
426
			else
427
				string_list_append(&transport->pack_lockfiles,
428
						   name);
429
		}
430
		else if (data->check_connectivity &&
431
			 data->transport_options.check_self_contained_and_connected &&
432
			 !strcmp(buf.buf, "connectivity-ok"))
433
			data->transport_options.self_contained_and_connected = 1;
434
		else if (!buf.len)
435
			break;
436
		else
437
			warning(_("%s unexpectedly said: '%s'"), data->name, buf.buf);
438
	}
439
	strbuf_release(&buf);
440

441
	reprepare_packed_git(the_repository);
442
	return 0;
443
}
444

445
static int get_importer(struct transport *transport, struct child_process *fastimport)
446
{
447
	struct child_process *helper = get_helper(transport);
448
	struct helper_data *data = transport->data;
449
	int cat_blob_fd, code;
450
	child_process_init(fastimport);
451
	fastimport->in = xdup(helper->out);
452
	strvec_push(&fastimport->args, "fast-import");
453
	strvec_push(&fastimport->args, "--allow-unsafe-features");
454
	strvec_push(&fastimport->args, debug ? "--stats" : "--quiet");
455

456
	if (data->bidi_import) {
457
		cat_blob_fd = xdup(helper->in);
458
		strvec_pushf(&fastimport->args, "--cat-blob-fd=%d", cat_blob_fd);
459
	}
460
	fastimport->git_cmd = 1;
461

462
	code = start_command(fastimport);
463
	return code;
464
}
465

466
static int get_exporter(struct transport *transport,
467
			struct child_process *fastexport,
468
			struct string_list *revlist_args)
469
{
470
	struct helper_data *data = transport->data;
471
	struct child_process *helper = get_helper(transport);
472
	int i;
473

474
	child_process_init(fastexport);
475

476
	/* we need to duplicate helper->in because we want to use it after
477
	 * fastexport is done with it. */
478
	fastexport->out = dup(helper->in);
479
	strvec_push(&fastexport->args, "fast-export");
480
	strvec_push(&fastexport->args, "--use-done-feature");
481
	strvec_push(&fastexport->args, data->signed_tags ?
482
		"--signed-tags=verbatim" : "--signed-tags=warn-strip");
483
	if (data->export_marks)
484
		strvec_pushf(&fastexport->args, "--export-marks=%s.tmp", data->export_marks);
485
	if (data->import_marks)
486
		strvec_pushf(&fastexport->args, "--import-marks=%s", data->import_marks);
487

488
	for (i = 0; i < revlist_args->nr; i++)
489
		strvec_push(&fastexport->args, revlist_args->items[i].string);
490

491
	fastexport->git_cmd = 1;
492
	return start_command(fastexport);
493
}
494

495
static int fetch_with_import(struct transport *transport,
496
			     int nr_heads, struct ref **to_fetch)
497
{
498
	struct child_process fastimport;
499
	struct helper_data *data = transport->data;
500
	int i;
501
	struct ref *posn;
502
	struct strbuf buf = STRBUF_INIT;
503

504
	get_helper(transport);
505

506
	if (get_importer(transport, &fastimport))
507
		die(_("couldn't run fast-import"));
508

509
	for (i = 0; i < nr_heads; i++) {
510
		posn = to_fetch[i];
511
		if (posn->status & REF_STATUS_UPTODATE)
512
			continue;
513

514
		strbuf_addf(&buf, "import %s\n",
515
			    posn->symref ? posn->symref : posn->name);
516
		sendline(data, &buf);
517
		strbuf_reset(&buf);
518
	}
519

520
	write_constant(data->helper->in, "\n");
521
	/*
522
	 * remote-helpers that advertise the bidi-import capability are required to
523
	 * buffer the complete batch of import commands until this newline before
524
	 * sending data to fast-import.
525
	 * These helpers read back data from fast-import on their stdin, which could
526
	 * be mixed with import commands, otherwise.
527
	 */
528

529
	if (finish_command(&fastimport))
530
		die(_("error while running fast-import"));
531

532
	/*
533
	 * The fast-import stream of a remote helper that advertises
534
	 * the "refspec" capability writes to the refs named after the
535
	 * right hand side of the first refspec matching each ref we
536
	 * were fetching.
537
	 *
538
	 * (If no "refspec" capability was specified, for historical
539
	 * reasons we default to the equivalent of *:*.)
540
	 *
541
	 * Store the result in to_fetch[i].old_sha1.  Callers such
542
	 * as "git fetch" can use the value to write feedback to the
543
	 * terminal, populate FETCH_HEAD, and determine what new value
544
	 * should be written to peer_ref if the update is a
545
	 * fast-forward or this is a forced update.
546
	 */
547
	for (i = 0; i < nr_heads; i++) {
548
		char *private, *name;
549
		posn = to_fetch[i];
550
		if (posn->status & REF_STATUS_UPTODATE)
551
			continue;
552
		name = posn->symref ? posn->symref : posn->name;
553
		if (data->rs.nr)
554
			private = apply_refspecs(&data->rs, name);
555
		else
556
			private = xstrdup(name);
557
		if (private) {
558
			if (refs_read_ref(get_main_ref_store(the_repository), private, &posn->old_oid) < 0)
559
				die(_("could not read ref %s"), private);
560
			free(private);
561
		}
562
	}
563
	strbuf_release(&buf);
564
	return 0;
565
}
566

567
static int run_connect(struct transport *transport, struct strbuf *cmdbuf)
568
{
569
	struct helper_data *data = transport->data;
570
	int ret = 0;
571
	int duped;
572
	FILE *input;
573
	struct child_process *helper;
574

575
	helper = get_helper(transport);
576

577
	/*
578
	 * Yes, dup the pipe another time, as we need unbuffered version
579
	 * of input pipe as FILE*. fclose() closes the underlying fd and
580
	 * stream buffering only can be changed before first I/O operation
581
	 * on it.
582
	 */
583
	duped = dup(helper->out);
584
	if (duped < 0)
585
		die_errno(_("can't dup helper output fd"));
586
	input = xfdopen(duped, "r");
587
	setvbuf(input, NULL, _IONBF, 0);
588

589
	sendline(data, cmdbuf);
590
	if (recvline_fh(input, cmdbuf))
591
		exit(128);
592

593
	if (!strcmp(cmdbuf->buf, "")) {
594
		data->no_disconnect_req = 1;
595
		if (debug)
596
			fprintf(stderr, "Debug: Smart transport connection "
597
				"ready.\n");
598
		ret = 1;
599
	} else if (!strcmp(cmdbuf->buf, "fallback")) {
600
		if (debug)
601
			fprintf(stderr, "Debug: Falling back to dumb "
602
				"transport.\n");
603
	} else {
604
		die(_("unknown response to connect: %s"),
605
		    cmdbuf->buf);
606
	}
607

608
	fclose(input);
609
	return ret;
610
}
611

612
static int process_connect_service(struct transport *transport,
613
				   const char *name, const char *exec)
614
{
615
	struct helper_data *data = transport->data;
616
	struct strbuf cmdbuf = STRBUF_INIT;
617
	int ret = 0;
618

619
	/*
620
	 * Handle --upload-pack and friends. This is fire and forget...
621
	 * just warn if it fails.
622
	 */
623
	if (strcmp(name, exec)) {
624
		int r = set_helper_option(transport, "servpath", exec);
625
		if (r > 0)
626
			warning(_("setting remote service path not supported by protocol"));
627
		else if (r < 0)
628
			warning(_("invalid remote service path"));
629
	}
630

631
	if (data->connect) {
632
		strbuf_addf(&cmdbuf, "connect %s\n", name);
633
		ret = run_connect(transport, &cmdbuf);
634
	} else if (data->stateless_connect &&
635
		   (get_protocol_version_config() == protocol_v2) &&
636
		   (!strcmp("git-upload-pack", name) ||
637
		    !strcmp("git-upload-archive", name))) {
638
		strbuf_addf(&cmdbuf, "stateless-connect %s\n", name);
639
		ret = run_connect(transport, &cmdbuf);
640
		if (ret)
641
			transport->stateless_rpc = 1;
642
	}
643

644
	strbuf_release(&cmdbuf);
645
	return ret;
646
}
647

648
static int process_connect(struct transport *transport,
649
				     int for_push)
650
{
651
	struct helper_data *data = transport->data;
652
	const char *name;
653
	const char *exec;
654
	int ret;
655

656
	name = for_push ? "git-receive-pack" : "git-upload-pack";
657
	if (for_push)
658
		exec = data->transport_options.receivepack;
659
	else
660
		exec = data->transport_options.uploadpack;
661

662
	ret = process_connect_service(transport, name, exec);
663
	if (ret)
664
		do_take_over(transport);
665
	return ret;
666
}
667

668
static int connect_helper(struct transport *transport, const char *name,
669
		   const char *exec, int fd[2])
670
{
671
	struct helper_data *data = transport->data;
672

673
	/* Get_helper so connect is inited. */
674
	get_helper(transport);
675

676
	if (!process_connect_service(transport, name, exec))
677
		die(_("can't connect to subservice %s"), name);
678

679
	fd[0] = data->helper->out;
680
	fd[1] = data->helper->in;
681

682
	do_take_over(transport);
683
	return 0;
684
}
685

686
static struct ref *get_refs_list_using_list(struct transport *transport,
687
					    int for_push);
688

689
static int fetch_refs(struct transport *transport,
690
		      int nr_heads, struct ref **to_fetch)
691
{
692
	struct helper_data *data = transport->data;
693
	int i, count;
694

695
	get_helper(transport);
696

697
	if (process_connect(transport, 0))
698
		return transport->vtable->fetch_refs(transport, nr_heads, to_fetch);
699

700
	/*
701
	 * If we reach here, then the server, the client, and/or the transport
702
	 * helper does not support protocol v2. --negotiate-only requires
703
	 * protocol v2.
704
	 */
705
	if (data->transport_options.acked_commits) {
706
		warning(_("--negotiate-only requires protocol v2"));
707
		return -1;
708
	}
709

710
	if (!data->get_refs_list_called)
711
		get_refs_list_using_list(transport, 0);
712

713
	count = 0;
714
	for (i = 0; i < nr_heads; i++)
715
		if (!(to_fetch[i]->status & REF_STATUS_UPTODATE))
716
			count++;
717

718
	if (!count)
719
		return 0;
720

721
	if (data->check_connectivity &&
722
	    data->transport_options.check_self_contained_and_connected)
723
		set_helper_option(transport, "check-connectivity", "true");
724

725
	if (transport->cloning)
726
		set_helper_option(transport, "cloning", "true");
727

728
	if (data->transport_options.update_shallow)
729
		set_helper_option(transport, "update-shallow", "true");
730

731
	if (data->transport_options.refetch)
732
		set_helper_option(transport, "refetch", "true");
733

734
	if (data->transport_options.filter_options.choice) {
735
		const char *spec = expand_list_objects_filter_spec(
736
			&data->transport_options.filter_options);
737
		set_helper_option(transport, "filter", spec);
738
	}
739

740
	if (data->transport_options.negotiation_tips)
741
		warning("Ignoring --negotiation-tip because the protocol does not support it.");
742

743
	if (data->fetch)
744
		return fetch_with_fetch(transport, nr_heads, to_fetch);
745

746
	if (data->import)
747
		return fetch_with_import(transport, nr_heads, to_fetch);
748

749
	return -1;
750
}
751

752
struct push_update_ref_state {
753
	struct ref *hint;
754
	struct ref_push_report *report;
755
	int new_report;
756
};
757

758
static int push_update_ref_status(struct strbuf *buf,
759
				   struct push_update_ref_state *state,
760
				   struct ref *remote_refs)
761
{
762
	char *refname, *msg;
763
	int status, forced = 0;
764

765
	if (starts_with(buf->buf, "option ")) {
766
		struct object_id old_oid, new_oid;
767
		const char *key, *val;
768
		char *p;
769

770
		if (!state->hint || !(state->report || state->new_report))
771
			die(_("'option' without a matching 'ok/error' directive"));
772
		if (state->new_report) {
773
			if (!state->hint->report) {
774
				CALLOC_ARRAY(state->hint->report, 1);
775
				state->report = state->hint->report;
776
			} else {
777
				state->report = state->hint->report;
778
				while (state->report->next)
779
					state->report = state->report->next;
780
				CALLOC_ARRAY(state->report->next, 1);
781
				state->report = state->report->next;
782
			}
783
			state->new_report = 0;
784
		}
785
		key = buf->buf + 7;
786
		p = strchr(key, ' ');
787
		if (p)
788
			*p++ = '\0';
789
		val = p;
790
		if (!strcmp(key, "refname"))
791
			state->report->ref_name = xstrdup_or_null(val);
792
		else if (!strcmp(key, "old-oid") && val &&
793
			 !parse_oid_hex(val, &old_oid, &val))
794
			state->report->old_oid = oiddup(&old_oid);
795
		else if (!strcmp(key, "new-oid") && val &&
796
			 !parse_oid_hex(val, &new_oid, &val))
797
			state->report->new_oid = oiddup(&new_oid);
798
		else if (!strcmp(key, "forced-update"))
799
			state->report->forced_update = 1;
800
		/* Not update remote namespace again. */
801
		return 1;
802
	}
803

804
	state->report = NULL;
805
	state->new_report = 0;
806

807
	if (starts_with(buf->buf, "ok ")) {
808
		status = REF_STATUS_OK;
809
		refname = buf->buf + 3;
810
	} else if (starts_with(buf->buf, "error ")) {
811
		status = REF_STATUS_REMOTE_REJECT;
812
		refname = buf->buf + 6;
813
	} else
814
		die(_("expected ok/error, helper said '%s'"), buf->buf);
815

816
	msg = strchr(refname, ' ');
817
	if (msg) {
818
		struct strbuf msg_buf = STRBUF_INIT;
819
		const char *end;
820

821
		*msg++ = '\0';
822
		if (!unquote_c_style(&msg_buf, msg, &end))
823
			msg = strbuf_detach(&msg_buf, NULL);
824
		else
825
			msg = xstrdup(msg);
826
		strbuf_release(&msg_buf);
827

828
		if (!strcmp(msg, "no match")) {
829
			status = REF_STATUS_NONE;
830
			FREE_AND_NULL(msg);
831
		}
832
		else if (!strcmp(msg, "up to date")) {
833
			status = REF_STATUS_UPTODATE;
834
			FREE_AND_NULL(msg);
835
		}
836
		else if (!strcmp(msg, "non-fast forward")) {
837
			status = REF_STATUS_REJECT_NONFASTFORWARD;
838
			FREE_AND_NULL(msg);
839
		}
840
		else if (!strcmp(msg, "already exists")) {
841
			status = REF_STATUS_REJECT_ALREADY_EXISTS;
842
			FREE_AND_NULL(msg);
843
		}
844
		else if (!strcmp(msg, "fetch first")) {
845
			status = REF_STATUS_REJECT_FETCH_FIRST;
846
			FREE_AND_NULL(msg);
847
		}
848
		else if (!strcmp(msg, "needs force")) {
849
			status = REF_STATUS_REJECT_NEEDS_FORCE;
850
			FREE_AND_NULL(msg);
851
		}
852
		else if (!strcmp(msg, "stale info")) {
853
			status = REF_STATUS_REJECT_STALE;
854
			FREE_AND_NULL(msg);
855
		}
856
		else if (!strcmp(msg, "remote ref updated since checkout")) {
857
			status = REF_STATUS_REJECT_REMOTE_UPDATED;
858
			FREE_AND_NULL(msg);
859
		}
860
		else if (!strcmp(msg, "forced update")) {
861
			forced = 1;
862
			FREE_AND_NULL(msg);
863
		}
864
		else if (!strcmp(msg, "expecting report")) {
865
			status = REF_STATUS_EXPECTING_REPORT;
866
			FREE_AND_NULL(msg);
867
		}
868
	}
869

870
	if (state->hint)
871
		state->hint = find_ref_by_name(state->hint, refname);
872
	if (!state->hint)
873
		state->hint = find_ref_by_name(remote_refs, refname);
874
	if (!state->hint) {
875
		warning(_("helper reported unexpected status of %s"), refname);
876
		return 1;
877
	}
878

879
	if (state->hint->status != REF_STATUS_NONE) {
880
		/*
881
		 * Earlier, the ref was marked not to be pushed, so ignore the ref
882
		 * status reported by the remote helper if the latter is 'no match'.
883
		 */
884
		if (status == REF_STATUS_NONE)
885
			return 1;
886
	}
887

888
	if (status == REF_STATUS_OK)
889
		state->new_report = 1;
890
	state->hint->status = status;
891
	state->hint->forced_update |= forced;
892
	state->hint->remote_status = msg;
893
	return !(status == REF_STATUS_OK);
894
}
895

896
static int push_update_refs_status(struct helper_data *data,
897
				    struct ref *remote_refs,
898
				    int flags)
899
{
900
	struct ref *ref;
901
	struct ref_push_report *report;
902
	struct strbuf buf = STRBUF_INIT;
903
	struct push_update_ref_state state = { remote_refs, NULL, 0 };
904

905
	for (;;) {
906
		if (recvline(data, &buf)) {
907
			strbuf_release(&buf);
908
			return 1;
909
		}
910
		if (!buf.len)
911
			break;
912
		push_update_ref_status(&buf, &state, remote_refs);
913
	}
914
	strbuf_release(&buf);
915

916
	if (flags & TRANSPORT_PUSH_DRY_RUN || !data->rs.nr || data->no_private_update)
917
		return 0;
918

919
	/* propagate back the update to the remote namespace */
920
	for (ref = remote_refs; ref; ref = ref->next) {
921
		char *private;
922

923
		if (ref->status != REF_STATUS_OK)
924
			continue;
925

926
		if (!ref->report) {
927
			private = apply_refspecs(&data->rs, ref->name);
928
			if (!private)
929
				continue;
930
			refs_update_ref(get_main_ref_store(the_repository),
931
					"update by helper", private,
932
					&(ref->new_oid),
933
					NULL, 0, 0);
934
			free(private);
935
		} else {
936
			for (report = ref->report; report; report = report->next) {
937
				private = apply_refspecs(&data->rs,
938
							 report->ref_name
939
							 ? report->ref_name
940
							 : ref->name);
941
				if (!private)
942
					continue;
943
				refs_update_ref(get_main_ref_store(the_repository),
944
						"update by helper", private,
945
						report->new_oid
946
						? report->new_oid
947
						: &(ref->new_oid),
948
						NULL, 0, 0);
949
				free(private);
950
			}
951
		}
952
	}
953
	return 0;
954
}
955

956
static void set_common_push_options(struct transport *transport,
957
				   const char *name, int flags)
958
{
959
	if (flags & TRANSPORT_PUSH_DRY_RUN) {
960
		if (set_helper_option(transport, "dry-run", "true") != 0)
961
			die(_("helper %s does not support dry-run"), name);
962
	} else if (flags & TRANSPORT_PUSH_CERT_ALWAYS) {
963
		if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "true") != 0)
964
			die(_("helper %s does not support --signed"), name);
965
	} else if (flags & TRANSPORT_PUSH_CERT_IF_ASKED) {
966
		if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "if-asked") != 0)
967
			die(_("helper %s does not support --signed=if-asked"), name);
968
	}
969

970
	if (flags & TRANSPORT_PUSH_ATOMIC)
971
		if (set_helper_option(transport, TRANS_OPT_ATOMIC, "true") != 0)
972
			die(_("helper %s does not support --atomic"), name);
973

974
	if (flags & TRANSPORT_PUSH_FORCE_IF_INCLUDES)
975
		if (set_helper_option(transport, TRANS_OPT_FORCE_IF_INCLUDES, "true") != 0)
976
			die(_("helper %s does not support --%s"),
977
			    name, TRANS_OPT_FORCE_IF_INCLUDES);
978

979
	if (flags & TRANSPORT_PUSH_OPTIONS) {
980
		struct string_list_item *item;
981
		for_each_string_list_item(item, transport->push_options)
982
			if (set_helper_option(transport, "push-option", item->string) != 0)
983
				die(_("helper %s does not support 'push-option'"), name);
984
	}
985
}
986

987
static int push_refs_with_push(struct transport *transport,
988
			       struct ref *remote_refs, int flags)
989
{
990
	int force_all = flags & TRANSPORT_PUSH_FORCE;
991
	int mirror = flags & TRANSPORT_PUSH_MIRROR;
992
	int atomic = flags & TRANSPORT_PUSH_ATOMIC;
993
	struct helper_data *data = transport->data;
994
	struct strbuf buf = STRBUF_INIT;
995
	struct ref *ref;
996
	struct string_list cas_options = STRING_LIST_INIT_DUP;
997
	struct string_list_item *cas_option;
998

999
	get_helper(transport);
1000
	if (!data->push)
1001
		return 1;
1002

1003
	for (ref = remote_refs; ref; ref = ref->next) {
1004
		if (!ref->peer_ref && !mirror)
1005
			continue;
1006

1007
		/* Check for statuses set by set_ref_status_for_push() */
1008
		switch (ref->status) {
1009
		case REF_STATUS_REJECT_NONFASTFORWARD:
1010
		case REF_STATUS_REJECT_STALE:
1011
		case REF_STATUS_REJECT_ALREADY_EXISTS:
1012
		case REF_STATUS_REJECT_REMOTE_UPDATED:
1013
			if (atomic) {
1014
				reject_atomic_push(remote_refs, mirror);
1015
				string_list_clear(&cas_options, 0);
1016
				return 0;
1017
			} else
1018
				continue;
1019
		case REF_STATUS_UPTODATE:
1020
			continue;
1021
		default:
1022
			; /* do nothing */
1023
		}
1024

1025
		if (force_all)
1026
			ref->force = 1;
1027

1028
		strbuf_addstr(&buf, "push ");
1029
		if (!ref->deletion) {
1030
			if (ref->force)
1031
				strbuf_addch(&buf, '+');
1032
			if (ref->peer_ref)
1033
				strbuf_addstr(&buf, ref->peer_ref->name);
1034
			else
1035
				strbuf_addstr(&buf, oid_to_hex(&ref->new_oid));
1036
		}
1037
		strbuf_addch(&buf, ':');
1038
		strbuf_addstr(&buf, ref->name);
1039
		strbuf_addch(&buf, '\n');
1040

1041
		/*
1042
		 * The "--force-with-lease" options without explicit
1043
		 * values to expect have already been expanded into
1044
		 * the ref->old_oid_expect[] field; we can ignore
1045
		 * transport->smart_options->cas altogether and instead
1046
		 * can enumerate them from the refs.
1047
		 */
1048
		if (ref->expect_old_sha1) {
1049
			struct strbuf cas = STRBUF_INIT;
1050
			strbuf_addf(&cas, "%s:%s",
1051
				    ref->name, oid_to_hex(&ref->old_oid_expect));
1052
			string_list_append_nodup(&cas_options,
1053
						 strbuf_detach(&cas, NULL));
1054
		}
1055
	}
1056
	if (buf.len == 0) {
1057
		string_list_clear(&cas_options, 0);
1058
		return 0;
1059
	}
1060

1061
	for_each_string_list_item(cas_option, &cas_options)
1062
		set_helper_option(transport, "cas", cas_option->string);
1063
	set_common_push_options(transport, data->name, flags);
1064

1065
	strbuf_addch(&buf, '\n');
1066
	sendline(data, &buf);
1067
	strbuf_release(&buf);
1068
	string_list_clear(&cas_options, 0);
1069

1070
	return push_update_refs_status(data, remote_refs, flags);
1071
}
1072

1073
static int push_refs_with_export(struct transport *transport,
1074
		struct ref *remote_refs, int flags)
1075
{
1076
	struct ref *ref;
1077
	struct child_process *helper, exporter;
1078
	struct helper_data *data = transport->data;
1079
	struct string_list revlist_args = STRING_LIST_INIT_DUP;
1080
	struct strbuf buf = STRBUF_INIT;
1081

1082
	if (!data->rs.nr)
1083
		die(_("remote-helper doesn't support push; refspec needed"));
1084

1085
	set_common_push_options(transport, data->name, flags);
1086
	if (flags & TRANSPORT_PUSH_FORCE) {
1087
		if (set_helper_option(transport, "force", "true") != 0)
1088
			warning(_("helper %s does not support '--force'"), data->name);
1089
	}
1090

1091
	helper = get_helper(transport);
1092

1093
	write_constant(helper->in, "export\n");
1094

1095
	for (ref = remote_refs; ref; ref = ref->next) {
1096
		char *private;
1097
		struct object_id oid;
1098

1099
		private = apply_refspecs(&data->rs, ref->name);
1100
		if (private && !repo_get_oid(the_repository, private, &oid)) {
1101
			strbuf_addf(&buf, "^%s", private);
1102
			string_list_append_nodup(&revlist_args,
1103
						 strbuf_detach(&buf, NULL));
1104
			oidcpy(&ref->old_oid, &oid);
1105
		}
1106
		free(private);
1107

1108
		if (ref->peer_ref) {
1109
			if (strcmp(ref->name, ref->peer_ref->name)) {
1110
				if (!ref->deletion) {
1111
					const char *name;
1112
					int flag;
1113

1114
					/* Follow symbolic refs (mainly for HEAD). */
1115
					name = refs_resolve_ref_unsafe(get_main_ref_store(the_repository),
1116
								       ref->peer_ref->name,
1117
								       RESOLVE_REF_READING,
1118
								       &oid,
1119
								       &flag);
1120
					if (!name || !(flag & REF_ISSYMREF))
1121
						name = ref->peer_ref->name;
1122

1123
					strbuf_addf(&buf, "%s:%s", name, ref->name);
1124
				} else
1125
					strbuf_addf(&buf, ":%s", ref->name);
1126

1127
				string_list_append(&revlist_args, "--refspec");
1128
				string_list_append(&revlist_args, buf.buf);
1129
				strbuf_release(&buf);
1130
			}
1131
			if (!ref->deletion)
1132
				string_list_append(&revlist_args, ref->peer_ref->name);
1133
		}
1134
	}
1135

1136
	if (get_exporter(transport, &exporter, &revlist_args))
1137
		die(_("couldn't run fast-export"));
1138

1139
	string_list_clear(&revlist_args, 1);
1140

1141
	if (finish_command(&exporter))
1142
		die(_("error while running fast-export"));
1143
	if (push_update_refs_status(data, remote_refs, flags))
1144
		return 1;
1145

1146
	if (data->export_marks) {
1147
		strbuf_addf(&buf, "%s.tmp", data->export_marks);
1148
		rename(buf.buf, data->export_marks);
1149
		strbuf_release(&buf);
1150
	}
1151

1152
	return 0;
1153
}
1154

1155
static int push_refs(struct transport *transport,
1156
		struct ref *remote_refs, int flags)
1157
{
1158
	struct helper_data *data = transport->data;
1159

1160
	if (process_connect(transport, 1))
1161
		return transport->vtable->push_refs(transport, remote_refs, flags);
1162

1163
	if (!remote_refs) {
1164
		fprintf(stderr,
1165
			_("No refs in common and none specified; doing nothing.\n"
1166
			  "Perhaps you should specify a branch.\n"));
1167
		return 0;
1168
	}
1169

1170
	if (data->push)
1171
		return push_refs_with_push(transport, remote_refs, flags);
1172

1173
	if (data->export)
1174
		return push_refs_with_export(transport, remote_refs, flags);
1175

1176
	return -1;
1177
}
1178

1179

1180
static int has_attribute(const char *attrs, const char *attr)
1181
{
1182
	int len;
1183
	if (!attrs)
1184
		return 0;
1185

1186
	len = strlen(attr);
1187
	for (;;) {
1188
		const char *space = strchrnul(attrs, ' ');
1189
		if (len == space - attrs && !strncmp(attrs, attr, len))
1190
			return 1;
1191
		if (!*space)
1192
			return 0;
1193
		attrs = space + 1;
1194
	}
1195
}
1196

1197
static struct ref *get_refs_list(struct transport *transport, int for_push,
1198
				 struct transport_ls_refs_options *transport_options)
1199
{
1200
	get_helper(transport);
1201

1202
	if (process_connect(transport, for_push))
1203
		return transport->vtable->get_refs_list(transport, for_push,
1204
							transport_options);
1205

1206
	return get_refs_list_using_list(transport, for_push);
1207
}
1208

1209
static struct ref *get_refs_list_using_list(struct transport *transport,
1210
					    int for_push)
1211
{
1212
	struct helper_data *data = transport->data;
1213
	struct child_process *helper;
1214
	struct ref *ret = NULL;
1215
	struct ref **tail = &ret;
1216
	struct ref *posn;
1217
	struct strbuf buf = STRBUF_INIT;
1218

1219
	data->get_refs_list_called = 1;
1220
	helper = get_helper(transport);
1221

1222
	if (data->object_format)
1223
		set_helper_option(transport, "object-format", "true");
1224

1225
	if (data->push && for_push)
1226
		write_constant(helper->in, "list for-push\n");
1227
	else
1228
		write_constant(helper->in, "list\n");
1229

1230
	while (1) {
1231
		char *eov, *eon;
1232
		if (recvline(data, &buf))
1233
			exit(128);
1234

1235
		if (!*buf.buf)
1236
			break;
1237
		else if (buf.buf[0] == ':') {
1238
			const char *value;
1239
			if (skip_prefix(buf.buf, ":object-format ", &value)) {
1240
				int algo = hash_algo_by_name(value);
1241
				if (algo == GIT_HASH_UNKNOWN)
1242
					die(_("unsupported object format '%s'"),
1243
					    value);
1244
				transport->hash_algo = &hash_algos[algo];
1245
			}
1246
			continue;
1247
		}
1248

1249
		eov = strchr(buf.buf, ' ');
1250
		if (!eov)
1251
			die(_("malformed response in ref list: %s"), buf.buf);
1252
		eon = strchr(eov + 1, ' ');
1253
		*eov = '\0';
1254
		if (eon)
1255
			*eon = '\0';
1256
		*tail = alloc_ref(eov + 1);
1257
		if (buf.buf[0] == '@')
1258
			(*tail)->symref = xstrdup(buf.buf + 1);
1259
		else if (buf.buf[0] != '?')
1260
			get_oid_hex_algop(buf.buf, &(*tail)->old_oid, transport->hash_algo);
1261
		if (eon) {
1262
			if (has_attribute(eon + 1, "unchanged")) {
1263
				(*tail)->status |= REF_STATUS_UPTODATE;
1264
				if (refs_read_ref(get_main_ref_store(the_repository), (*tail)->name, &(*tail)->old_oid) < 0)
1265
					die(_("could not read ref %s"),
1266
					    (*tail)->name);
1267
			}
1268
		}
1269
		tail = &((*tail)->next);
1270
	}
1271
	if (debug)
1272
		fprintf(stderr, "Debug: Read ref listing.\n");
1273
	strbuf_release(&buf);
1274

1275
	for (posn = ret; posn; posn = posn->next)
1276
		resolve_remote_symref(posn, ret);
1277

1278
	return ret;
1279
}
1280

1281
static int get_bundle_uri(struct transport *transport)
1282
{
1283
	get_helper(transport);
1284

1285
	if (process_connect(transport, 0))
1286
		return transport->vtable->get_bundle_uri(transport);
1287

1288
	return -1;
1289
}
1290

1291
static struct transport_vtable vtable = {
1292
	.set_option	= set_helper_option,
1293
	.get_refs_list	= get_refs_list,
1294
	.get_bundle_uri = get_bundle_uri,
1295
	.fetch_refs	= fetch_refs,
1296
	.push_refs	= push_refs,
1297
	.connect	= connect_helper,
1298
	.disconnect	= release_helper
1299
};
1300

1301
int transport_helper_init(struct transport *transport, const char *name)
1302
{
1303
	struct helper_data *data = xcalloc(1, sizeof(*data));
1304
	data->name = xstrdup(name);
1305

1306
	transport_check_allowed(name);
1307

1308
	if (getenv("GIT_TRANSPORT_HELPER_DEBUG"))
1309
		debug = 1;
1310

1311
	list_objects_filter_init(&data->transport_options.filter_options);
1312

1313
	transport->data = data;
1314
	transport->vtable = &vtable;
1315
	transport->smart_options = &(data->transport_options);
1316
	return 0;
1317
}
1318

1319
/*
1320
 * Linux pipes can buffer 65536 bytes at once (and most platforms can
1321
 * buffer less), so attempt reads and writes with up to that size.
1322
 */
1323
#define BUFFERSIZE 65536
1324
/* This should be enough to hold debugging message. */
1325
#define PBUFFERSIZE 8192
1326

1327
/* Print bidirectional transfer loop debug message. */
1328
__attribute__((format (printf, 1, 2)))
1329
static void transfer_debug(const char *fmt, ...)
1330
{
1331
	/*
1332
	 * NEEDSWORK: This function is sometimes used from multiple threads, and
1333
	 * we end up using debug_enabled racily. That "should not matter" since
1334
	 * we always write the same value, but it's still wrong. This function
1335
	 * is listed in .tsan-suppressions for the time being.
1336
	 */
1337

1338
	va_list args;
1339
	char msgbuf[PBUFFERSIZE];
1340
	static int debug_enabled = -1;
1341

1342
	if (debug_enabled < 0)
1343
		debug_enabled = getenv("GIT_TRANSLOOP_DEBUG") ? 1 : 0;
1344
	if (!debug_enabled)
1345
		return;
1346

1347
	va_start(args, fmt);
1348
	vsnprintf(msgbuf, PBUFFERSIZE, fmt, args);
1349
	va_end(args);
1350
	fprintf(stderr, "Transfer loop debugging: %s\n", msgbuf);
1351
}
1352

1353
/* Stream state: More data may be coming in this direction. */
1354
#define SSTATE_TRANSFERRING 0
1355
/*
1356
 * Stream state: No more data coming in this direction, flushing rest of
1357
 * data.
1358
 */
1359
#define SSTATE_FLUSHING 1
1360
/* Stream state: Transfer in this direction finished. */
1361
#define SSTATE_FINISHED 2
1362

1363
#define STATE_NEEDS_READING(state) ((state) <= SSTATE_TRANSFERRING)
1364
#define STATE_NEEDS_WRITING(state) ((state) <= SSTATE_FLUSHING)
1365
#define STATE_NEEDS_CLOSING(state) ((state) == SSTATE_FLUSHING)
1366

1367
/* Unidirectional transfer. */
1368
struct unidirectional_transfer {
1369
	/* Source */
1370
	int src;
1371
	/* Destination */
1372
	int dest;
1373
	/* Is source socket? */
1374
	int src_is_sock;
1375
	/* Is destination socket? */
1376
	int dest_is_sock;
1377
	/* Transfer state (TRANSFERRING/FLUSHING/FINISHED) */
1378
	int state;
1379
	/* Buffer. */
1380
	char buf[BUFFERSIZE];
1381
	/* Buffer used. */
1382
	size_t bufuse;
1383
	/* Name of source. */
1384
	const char *src_name;
1385
	/* Name of destination. */
1386
	const char *dest_name;
1387
};
1388

1389
/* Closes the target (for writing) if transfer has finished. */
1390
static void udt_close_if_finished(struct unidirectional_transfer *t)
1391
{
1392
	if (STATE_NEEDS_CLOSING(t->state) && !t->bufuse) {
1393
		t->state = SSTATE_FINISHED;
1394
		if (t->dest_is_sock)
1395
			shutdown(t->dest, SHUT_WR);
1396
		else
1397
			close(t->dest);
1398
		transfer_debug("Closed %s.", t->dest_name);
1399
	}
1400
}
1401

1402
/*
1403
 * Tries to read data from source into buffer. If buffer is full,
1404
 * no data is read. Returns 0 on success, -1 on error.
1405
 */
1406
static int udt_do_read(struct unidirectional_transfer *t)
1407
{
1408
	ssize_t bytes;
1409

1410
	if (t->bufuse == BUFFERSIZE)
1411
		return 0;	/* No space for more. */
1412

1413
	transfer_debug("%s is readable", t->src_name);
1414
	bytes = xread(t->src, t->buf + t->bufuse, BUFFERSIZE - t->bufuse);
1415
	if (bytes < 0) {
1416
		error_errno(_("read(%s) failed"), t->src_name);
1417
		return -1;
1418
	} else if (bytes == 0) {
1419
		transfer_debug("%s EOF (with %i bytes in buffer)",
1420
			t->src_name, (int)t->bufuse);
1421
		t->state = SSTATE_FLUSHING;
1422
	} else if (bytes > 0) {
1423
		t->bufuse += bytes;
1424
		transfer_debug("Read %i bytes from %s (buffer now at %i)",
1425
			(int)bytes, t->src_name, (int)t->bufuse);
1426
	}
1427
	return 0;
1428
}
1429

1430
/* Tries to write data from buffer into destination. If buffer is empty,
1431
 * no data is written. Returns 0 on success, -1 on error.
1432
 */
1433
static int udt_do_write(struct unidirectional_transfer *t)
1434
{
1435
	ssize_t bytes;
1436

1437
	if (t->bufuse == 0)
1438
		return 0;	/* Nothing to write. */
1439

1440
	transfer_debug("%s is writable", t->dest_name);
1441
	bytes = xwrite(t->dest, t->buf, t->bufuse);
1442
	if (bytes < 0) {
1443
		error_errno(_("write(%s) failed"), t->dest_name);
1444
		return -1;
1445
	} else if (bytes > 0) {
1446
		t->bufuse -= bytes;
1447
		if (t->bufuse)
1448
			memmove(t->buf, t->buf + bytes, t->bufuse);
1449
		transfer_debug("Wrote %i bytes to %s (buffer now at %i)",
1450
			(int)bytes, t->dest_name, (int)t->bufuse);
1451
	}
1452
	return 0;
1453
}
1454

1455

1456
/* State of bidirectional transfer loop. */
1457
struct bidirectional_transfer_state {
1458
	/* Direction from program to git. */
1459
	struct unidirectional_transfer ptg;
1460
	/* Direction from git to program. */
1461
	struct unidirectional_transfer gtp;
1462
};
1463

1464
static void *udt_copy_task_routine(void *udt)
1465
{
1466
	struct unidirectional_transfer *t = (struct unidirectional_transfer *)udt;
1467
	while (t->state != SSTATE_FINISHED) {
1468
		if (STATE_NEEDS_READING(t->state))
1469
			if (udt_do_read(t))
1470
				return NULL;
1471
		if (STATE_NEEDS_WRITING(t->state))
1472
			if (udt_do_write(t))
1473
				return NULL;
1474
		if (STATE_NEEDS_CLOSING(t->state))
1475
			udt_close_if_finished(t);
1476
	}
1477
	return udt;	/* Just some non-NULL value. */
1478
}
1479

1480
#ifndef NO_PTHREADS
1481

1482
/*
1483
 * Join thread, with appropriate errors on failure. Name is name for the
1484
 * thread (for error messages). Returns 0 on success, 1 on failure.
1485
 */
1486
static int tloop_join(pthread_t thread, const char *name)
1487
{
1488
	int err;
1489
	void *tret;
1490
	err = pthread_join(thread, &tret);
1491
	if (!tret) {
1492
		error(_("%s thread failed"), name);
1493
		return 1;
1494
	}
1495
	if (err) {
1496
		error(_("%s thread failed to join: %s"), name, strerror(err));
1497
		return 1;
1498
	}
1499
	return 0;
1500
}
1501

1502
/*
1503
 * Spawn the transfer tasks and then wait for them. Returns 0 on success,
1504
 * -1 on failure.
1505
 */
1506
static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s)
1507
{
1508
	pthread_t gtp_thread;
1509
	pthread_t ptg_thread;
1510
	int err;
1511
	int ret = 0;
1512
	err = pthread_create(&gtp_thread, NULL, udt_copy_task_routine,
1513
		&s->gtp);
1514
	if (err)
1515
		die(_("can't start thread for copying data: %s"), strerror(err));
1516
	err = pthread_create(&ptg_thread, NULL, udt_copy_task_routine,
1517
		&s->ptg);
1518
	if (err)
1519
		die(_("can't start thread for copying data: %s"), strerror(err));
1520

1521
	ret |= tloop_join(gtp_thread, "Git to program copy");
1522
	ret |= tloop_join(ptg_thread, "Program to git copy");
1523
	return ret;
1524
}
1525
#else
1526

1527
/* Close the source and target (for writing) for transfer. */
1528
static void udt_kill_transfer(struct unidirectional_transfer *t)
1529
{
1530
	t->state = SSTATE_FINISHED;
1531
	/*
1532
	 * Socket read end left open isn't a disaster if nobody
1533
	 * attempts to read from it (mingw compat headers do not
1534
	 * have SHUT_RD)...
1535
	 *
1536
	 * We can't fully close the socket since otherwise gtp
1537
	 * task would first close the socket it sends data to
1538
	 * while closing the ptg file descriptors.
1539
	 */
1540
	if (!t->src_is_sock)
1541
		close(t->src);
1542
	if (t->dest_is_sock)
1543
		shutdown(t->dest, SHUT_WR);
1544
	else
1545
		close(t->dest);
1546
}
1547

1548
/*
1549
 * Join process, with appropriate errors on failure. Name is name for the
1550
 * process (for error messages). Returns 0 on success, 1 on failure.
1551
 */
1552
static int tloop_join(pid_t pid, const char *name)
1553
{
1554
	int tret;
1555
	if (waitpid(pid, &tret, 0) < 0) {
1556
		error_errno(_("%s process failed to wait"), name);
1557
		return 1;
1558
	}
1559
	if (!WIFEXITED(tret) || WEXITSTATUS(tret)) {
1560
		error(_("%s process failed"), name);
1561
		return 1;
1562
	}
1563
	return 0;
1564
}
1565

1566
/*
1567
 * Spawn the transfer tasks and then wait for them. Returns 0 on success,
1568
 * -1 on failure.
1569
 */
1570
static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s)
1571
{
1572
	pid_t pid1, pid2;
1573
	int ret = 0;
1574

1575
	/* Fork thread #1: git to program. */
1576
	pid1 = fork();
1577
	if (pid1 < 0)
1578
		die_errno(_("can't start thread for copying data"));
1579
	else if (pid1 == 0) {
1580
		udt_kill_transfer(&s->ptg);
1581
		exit(udt_copy_task_routine(&s->gtp) ? 0 : 1);
1582
	}
1583

1584
	/* Fork thread #2: program to git. */
1585
	pid2 = fork();
1586
	if (pid2 < 0)
1587
		die_errno(_("can't start thread for copying data"));
1588
	else if (pid2 == 0) {
1589
		udt_kill_transfer(&s->gtp);
1590
		exit(udt_copy_task_routine(&s->ptg) ? 0 : 1);
1591
	}
1592

1593
	/*
1594
	 * Close both streams in parent as to not interfere with
1595
	 * end of file detection and wait for both tasks to finish.
1596
	 */
1597
	udt_kill_transfer(&s->gtp);
1598
	udt_kill_transfer(&s->ptg);
1599
	ret |= tloop_join(pid1, "Git to program copy");
1600
	ret |= tloop_join(pid2, "Program to git copy");
1601
	return ret;
1602
}
1603
#endif
1604

1605
/*
1606
 * Copies data from stdin to output and from input to stdout simultaneously.
1607
 * Additionally filtering through given filter. If filter is NULL, uses
1608
 * identity filter.
1609
 */
1610
int bidirectional_transfer_loop(int input, int output)
1611
{
1612
	struct bidirectional_transfer_state state;
1613

1614
	/* Fill the state fields. */
1615
	state.ptg.src = input;
1616
	state.ptg.dest = 1;
1617
	state.ptg.src_is_sock = (input == output);
1618
	state.ptg.dest_is_sock = 0;
1619
	state.ptg.state = SSTATE_TRANSFERRING;
1620
	state.ptg.bufuse = 0;
1621
	state.ptg.src_name = "remote input";
1622
	state.ptg.dest_name = "stdout";
1623

1624
	state.gtp.src = 0;
1625
	state.gtp.dest = output;
1626
	state.gtp.src_is_sock = 0;
1627
	state.gtp.dest_is_sock = (input == output);
1628
	state.gtp.state = SSTATE_TRANSFERRING;
1629
	state.gtp.bufuse = 0;
1630
	state.gtp.src_name = "stdin";
1631
	state.gtp.dest_name = "remote output";
1632

1633
	return tloop_spawnwait_tasks(&state);
1634
}
1635

1636
void reject_atomic_push(struct ref *remote_refs, int mirror_mode)
1637
{
1638
	struct ref *ref;
1639

1640
	/* Mark other refs as failed */
1641
	for (ref = remote_refs; ref; ref = ref->next) {
1642
		if (!ref->peer_ref && !mirror_mode)
1643
			continue;
1644

1645
		switch (ref->status) {
1646
		case REF_STATUS_NONE:
1647
		case REF_STATUS_OK:
1648
		case REF_STATUS_EXPECTING_REPORT:
1649
			ref->status = REF_STATUS_ATOMIC_PUSH_FAILED;
1650
			continue;
1651
		default:
1652
			break; /* do nothing */
1653
		}
1654
	}
1655
	return;
1656
}
1657

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

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

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

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