transport.c 34.2 KB
Newer Older
1 2 3
#include "cache.h"
#include "transport.h"
#include "run-command.h"
4 5
#include "pkt-line.h"
#include "fetch-pack.h"
D
Daniel Barkalow 已提交
6
#include "send-pack.h"
7
#include "walker.h"
J
Johannes Schindelin 已提交
8
#include "bundle.h"
9 10
#include "dir.h"
#include "refs.h"
I
Ilari Liusvaara 已提交
11
#include "branch.h"
J
Jeff King 已提交
12
#include "url.h"
13
#include "submodule.h"
14
#include "string-list.h"
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

/* rsync support */

/*
 * We copy packed-refs and refs/ into a temporary file, then read the
 * loose refs recursively (sorting whenever possible), and then inserting
 * those packed refs that are not yet in the list (not validating, but
 * assuming that the file is sorted).
 *
 * Appears refactoring this from refs.c is too cumbersome.
 */

static int str_cmp(const void *a, const void *b)
{
	const char *s1 = a;
	const char *s2 = b;

	return strcmp(s1, s2);
}

/* path->buf + name_offset is expected to point to "refs/" */

static int read_loose_refs(struct strbuf *path, int name_offset,
		struct ref **tail)
{
	DIR *dir = opendir(path->buf);
	struct dirent *de;
	struct {
		char **entries;
		int nr, alloc;
	} list;
	int i, pathlen;

	if (!dir)
		return -1;

	memset (&list, 0, sizeof(list));

	while ((de = readdir(dir))) {
54
		if (is_dot_or_dotdot(de->d_name))
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
			continue;
		ALLOC_GROW(list.entries, list.nr + 1, list.alloc);
		list.entries[list.nr++] = xstrdup(de->d_name);
	}
	closedir(dir);

	/* sort the list */

	qsort(list.entries, list.nr, sizeof(char *), str_cmp);

	pathlen = path->len;
	strbuf_addch(path, '/');

	for (i = 0; i < list.nr; i++, strbuf_setlen(path, pathlen + 1)) {
		strbuf_addstr(path, list.entries[i]);
		if (read_loose_refs(path, name_offset, tail)) {
			int fd = open(path->buf, O_RDONLY);
			char buffer[40];
			struct ref *next;

			if (fd < 0)
				continue;
77
			next = alloc_ref(path->buf + name_offset);
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
			if (read_in_full(fd, buffer, 40) != 40 ||
					get_sha1_hex(buffer, next->old_sha1)) {
				close(fd);
				free(next);
				continue;
			}
			close(fd);
			(*tail)->next = next;
			*tail = next;
		}
	}
	strbuf_setlen(path, pathlen);

	for (i = 0; i < list.nr; i++)
		free(list.entries[i]);
	free(list.entries);

	return 0;
}

/* insert the packed refs for which no loose refs were found */

static void insert_packed_refs(const char *packed_refs, struct ref **list)
{
	FILE *f = fopen(packed_refs, "r");
	static char buffer[PATH_MAX];

	if (!f)
		return;

	for (;;) {
109 110
		int cmp = 0; /* assigned before used */
		int len;
111 112 113 114 115 116 117 118 119

		if (!fgets(buffer, sizeof(buffer), f)) {
			fclose(f);
			return;
		}

		if (hexval(buffer[0]) > 0xf)
			continue;
		len = strlen(buffer);
120
		if (len && buffer[len - 1] == '\n')
121 122 123 124 125 126 127 128
			buffer[--len] = '\0';
		if (len < 41)
			continue;
		while ((*list)->next &&
				(cmp = strcmp(buffer + 41,
				      (*list)->next->name)) > 0)
			list = &(*list)->next;
		if (!(*list)->next || cmp < 0) {
129
			struct ref *next = alloc_ref(buffer + 41);
130 131 132 133 134 135 136 137 138 139 140 141 142
			buffer[40] = '\0';
			if (get_sha1_hex(buffer, next->old_sha1)) {
				warning ("invalid SHA-1: %s", buffer);
				free(next);
				continue;
			}
			next->next = (*list)->next;
			(*list)->next = next;
			list = &(*list)->next;
		}
	}
}

I
Ilari Liusvaara 已提交
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
static void set_upstreams(struct transport *transport, struct ref *refs,
	int pretend)
{
	struct ref *ref;
	for (ref = refs; ref; ref = ref->next) {
		const char *localname;
		const char *tmp;
		const char *remotename;
		unsigned char sha[20];
		int flag = 0;
		/*
		 * Check suitability for tracking. Must be successful /
		 * already up-to-date ref create/modify (not delete).
		 */
		if (ref->status != REF_STATUS_OK &&
			ref->status != REF_STATUS_UPTODATE)
			continue;
		if (!ref->peer_ref)
			continue;
162
		if (is_null_sha1(ref->new_sha1))
I
Ilari Liusvaara 已提交
163 164 165 166 167
			continue;

		/* Follow symbolic refs (mainly for HEAD). */
		localname = ref->peer_ref->name;
		remotename = ref->name;
168
		tmp = resolve_ref_unsafe(localname, sha, 1, &flag);
I
Ilari Liusvaara 已提交
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
		if (tmp && flag & REF_ISSYMREF &&
			!prefixcmp(tmp, "refs/heads/"))
			localname = tmp;

		/* Both source and destination must be local branches. */
		if (!localname || prefixcmp(localname, "refs/heads/"))
			continue;
		if (!remotename || prefixcmp(remotename, "refs/heads/"))
			continue;

		if (!pretend)
			install_branch_config(BRANCH_CONFIG_VERBOSE,
				localname + 11, transport->remote->name,
				remotename);
		else
			printf("Would set upstream of '%s' to '%s' of '%s'\n",
				localname + 11, remotename + 11,
				transport->remote->name);
	}
}

190 191 192 193 194
static const char *rsync_url(const char *url)
{
	return prefixcmp(url, "rsync://") ? skip_prefix(url, "rsync:") : url;
}

195
static struct ref *get_refs_via_rsync(struct transport *transport, int for_push)
196 197
{
	struct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;
S
Stephen Boyd 已提交
198
	struct ref dummy = {NULL}, *tail = &dummy;
199 200 201 202
	struct child_process rsync;
	const char *args[5];
	int temp_dir_len;

203 204 205
	if (for_push)
		return NULL;

206 207 208 209
	/* copy the refs to the temporary directory */

	strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
	if (!mkdtemp(temp_dir.buf))
210
		die_errno ("Could not make temporary directory");
211 212
	temp_dir_len = temp_dir.len;

213
	strbuf_addstr(&buf, rsync_url(transport->url));
214 215 216 217 218 219
	strbuf_addstr(&buf, "/refs");

	memset(&rsync, 0, sizeof(rsync));
	rsync.argv = args;
	rsync.stdout_to_stderr = 1;
	args[0] = "rsync";
J
Jeff King 已提交
220
	args[1] = (transport->verbose > 1) ? "-rv" : "-r";
221 222 223 224 225 226 227 228
	args[2] = buf.buf;
	args[3] = temp_dir.buf;
	args[4] = NULL;

	if (run_command(&rsync))
		die ("Could not run rsync to get refs");

	strbuf_reset(&buf);
229
	strbuf_addstr(&buf, rsync_url(transport->url));
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
	strbuf_addstr(&buf, "/packed-refs");

	args[2] = buf.buf;

	if (run_command(&rsync))
		die ("Could not run rsync to get refs");

	/* read the copied refs */

	strbuf_addstr(&temp_dir, "/refs");
	read_loose_refs(&temp_dir, temp_dir_len + 1, &tail);
	strbuf_setlen(&temp_dir, temp_dir_len);

	tail = &dummy;
	strbuf_addstr(&temp_dir, "/packed-refs");
	insert_packed_refs(temp_dir.buf, &tail);
	strbuf_setlen(&temp_dir, temp_dir_len);

	if (remove_dir_recursively(&temp_dir, 0))
		warning ("Error removing temporary directory %s.",
				temp_dir.buf);

	strbuf_release(&buf);
	strbuf_release(&temp_dir);

	return dummy.next;
}

static int fetch_objs_via_rsync(struct transport *transport,
D
Daniel Barkalow 已提交
259
				int nr_objs, struct ref **to_fetch)
260 261 262 263 264 265
{
	struct strbuf buf = STRBUF_INIT;
	struct child_process rsync;
	const char *args[8];
	int result;

266
	strbuf_addstr(&buf, rsync_url(transport->url));
267 268 269 270 271 272
	strbuf_addstr(&buf, "/objects/");

	memset(&rsync, 0, sizeof(rsync));
	rsync.argv = args;
	rsync.stdout_to_stderr = 1;
	args[0] = "rsync";
J
Jeff King 已提交
273
	args[1] = (transport->verbose > 1) ? "-rv" : "-r";
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
	args[2] = "--ignore-existing";
	args[3] = "--exclude";
	args[4] = "info";
	args[5] = buf.buf;
	args[6] = get_object_directory();
	args[7] = NULL;

	/* NEEDSWORK: handle one level of alternates */
	result = run_command(&rsync);

	strbuf_release(&buf);

	return result;
}

static int write_one_ref(const char *name, const unsigned char *sha1,
		int flags, void *data)
{
	struct strbuf *buf = data;
	int len = buf->len;
	FILE *f;

	/* when called via for_each_ref(), flags is non-zero */
	if (flags && prefixcmp(name, "refs/heads/") &&
			prefixcmp(name, "refs/tags/"))
		return 0;

	strbuf_addstr(buf, name);
	if (safe_create_leading_directories(buf->buf) ||
			!(f = fopen(buf->buf, "w")) ||
			fprintf(f, "%s\n", sha1_to_hex(sha1)) < 0 ||
			fclose(f))
		return error("problems writing temporary file %s", buf->buf);
	strbuf_setlen(buf, len);
	return 0;
}

static int write_refs_to_temp_dir(struct strbuf *temp_dir,
		int refspec_nr, const char **refspec)
{
	int i;

	for (i = 0; i < refspec_nr; i++) {
		unsigned char sha1[20];
		char *ref;

		if (dwim_ref(refspec[i], strlen(refspec[i]), sha1, &ref) != 1)
			return error("Could not get ref %s", refspec[i]);

		if (write_one_ref(ref, sha1, 0, temp_dir)) {
			free(ref);
			return -1;
		}
		free(ref);
	}
	return 0;
}

static int rsync_transport_push(struct transport *transport,
		int refspec_nr, const char **refspec, int flags)
{
	struct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;
	int result = 0, i;
	struct child_process rsync;
338
	const char *args[10];
339

A
Andy Whitcroft 已提交
340 341 342
	if (flags & TRANSPORT_PUSH_MIRROR)
		return error("rsync transport does not support mirror mode");

343 344
	/* first push the objects */

345
	strbuf_addstr(&buf, rsync_url(transport->url));
346 347 348 349 350
	strbuf_addch(&buf, '/');

	memset(&rsync, 0, sizeof(rsync));
	rsync.argv = args;
	rsync.stdout_to_stderr = 1;
351 352 353 354 355
	i = 0;
	args[i++] = "rsync";
	args[i++] = "-a";
	if (flags & TRANSPORT_PUSH_DRY_RUN)
		args[i++] = "--dry-run";
J
Jeff King 已提交
356
	if (transport->verbose > 1)
357 358 359 360 361 362 363
		args[i++] = "-v";
	args[i++] = "--ignore-existing";
	args[i++] = "--exclude";
	args[i++] = "info";
	args[i++] = get_object_directory();
	args[i++] = buf.buf;
	args[i++] = NULL;
364 365

	if (run_command(&rsync))
366 367
		return error("Could not push objects to %s",
				rsync_url(transport->url));
368 369 370 371 372

	/* copy the refs to the temporary directory; they could be packed. */

	strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
	if (!mkdtemp(temp_dir.buf))
373
		die_errno ("Could not make temporary directory");
374 375 376 377 378 379 380 381
	strbuf_addch(&temp_dir, '/');

	if (flags & TRANSPORT_PUSH_ALL) {
		if (for_each_ref(write_one_ref, &temp_dir))
			return -1;
	} else if (write_refs_to_temp_dir(&temp_dir, refspec_nr, refspec))
		return -1;

382 383 384 385 386
	i = 2;
	if (flags & TRANSPORT_PUSH_DRY_RUN)
		args[i++] = "--dry-run";
	if (!(flags & TRANSPORT_PUSH_FORCE))
		args[i++] = "--ignore-existing";
387
	args[i++] = temp_dir.buf;
388
	args[i++] = rsync_url(transport->url);
389 390
	args[i++] = NULL;
	if (run_command(&rsync))
391 392
		result = error("Could not push to %s",
				rsync_url(transport->url));
393 394 395 396 397 398 399 400 401 402

	if (remove_dir_recursively(&temp_dir, 0))
		warning ("Could not remove temporary directory %s.",
				temp_dir.buf);

	strbuf_release(&buf);
	strbuf_release(&temp_dir);

	return result;
}
403

J
Johannes Schindelin 已提交
404 405 406 407 408
struct bundle_transport_data {
	int fd;
	struct bundle_header header;
};

409
static struct ref *get_refs_from_bundle(struct transport *transport, int for_push)
J
Johannes Schindelin 已提交
410 411 412 413 414
{
	struct bundle_transport_data *data = transport->data;
	struct ref *result = NULL;
	int i;

415 416 417
	if (for_push)
		return NULL;

J
Johannes Schindelin 已提交
418 419 420 421 422 423 424
	if (data->fd > 0)
		close(data->fd);
	data->fd = read_bundle_header(transport->url, &data->header);
	if (data->fd < 0)
		die ("Could not read bundle '%s'.", transport->url);
	for (i = 0; i < data->header.references.nr; i++) {
		struct ref_list_entry *e = data->header.references.list + i;
425
		struct ref *ref = alloc_ref(e->name);
J
Johannes Schindelin 已提交
426 427 428 429 430 431 432
		hashcpy(ref->old_sha1, e->sha1);
		ref->next = result;
		result = ref;
	}
	return result;
}

433
static int fetch_refs_from_bundle(struct transport *transport,
D
Daniel Barkalow 已提交
434
			       int nr_heads, struct ref **to_fetch)
J
Johannes Schindelin 已提交
435 436
{
	struct bundle_transport_data *data = transport->data;
437 438
	return unbundle(&data->header, data->fd,
			transport->progress ? BUNDLE_VERBOSE : 0);
J
Johannes Schindelin 已提交
439 440 441 442 443 444 445
}

static int close_bundle(struct transport *transport)
{
	struct bundle_transport_data *data = transport->data;
	if (data->fd > 0)
		close(data->fd);
446
	free(data);
J
Johannes Schindelin 已提交
447 448 449
	return 0;
}

450
struct git_transport_data {
451
	struct git_transport_options options;
452 453
	struct child_process *conn;
	int fd[2];
I
Ilari Liusvaara 已提交
454
	unsigned got_remote_heads : 1;
455
	struct extra_have_objects extra_have;
456 457
};

458
static int set_git_option(struct git_transport_options *opts,
459 460
			  const char *name, const char *value)
{
461
	if (!strcmp(name, TRANS_OPT_UPLOADPACK)) {
462
		opts->uploadpack = value;
463 464
		return 0;
	} else if (!strcmp(name, TRANS_OPT_RECEIVEPACK)) {
465
		opts->receivepack = value;
466 467
		return 0;
	} else if (!strcmp(name, TRANS_OPT_THIN)) {
468
		opts->thin = !!value;
469
		return 0;
470
	} else if (!strcmp(name, TRANS_OPT_FOLLOWTAGS)) {
471
		opts->followtags = !!value;
472
		return 0;
473
	} else if (!strcmp(name, TRANS_OPT_KEEP)) {
474
		opts->keep = !!value;
475 476 477
		return 0;
	} else if (!strcmp(name, TRANS_OPT_DEPTH)) {
		if (!value)
478
			opts->depth = 0;
479 480 481 482 483 484
		else {
			char *end;
			opts->depth = strtol(value, &end, 0);
			if (*end)
				die("transport: invalid depth option '%s'", value);
		}
485
		return 0;
486 487 488 489
	}
	return 1;
}

490
static int connect_setup(struct transport *transport, int for_push, int verbose)
491 492
{
	struct git_transport_data *data = transport->data;
I
Ilari Liusvaara 已提交
493 494 495 496

	if (data->conn)
		return 0;

497 498 499
	data->conn = git_connect(data->fd, transport->url,
				 for_push ? data->options.receivepack :
				 data->options.uploadpack,
500
				 verbose ? CONNECT_VERBOSE : 0);
I
Ilari Liusvaara 已提交
501

502 503 504
	return 0;
}

505
static struct ref *get_refs_via_connect(struct transport *transport, int for_push)
506 507 508 509
{
	struct git_transport_data *data = transport->data;
	struct ref *refs;

510
	connect_setup(transport, for_push, 0);
511
	get_remote_heads(data->fd[0], NULL, 0, &refs,
512
			 for_push ? REF_NORMAL : 0, &data->extra_have);
I
Ilari Liusvaara 已提交
513
	data->got_remote_heads = 1;
514 515 516 517

	return refs;
}

518
static int fetch_refs_via_pack(struct transport *transport,
D
Daniel Barkalow 已提交
519
			       int nr_heads, struct ref **to_fetch)
520 521
{
	struct git_transport_data *data = transport->data;
522
	const struct ref *refs;
523 524
	char *dest = xstrdup(transport->url);
	struct fetch_pack_args args;
525
	struct ref *refs_tmp = NULL;
526

527
	memset(&args, 0, sizeof(args));
528 529
	args.uploadpack = data->options.uploadpack;
	args.keep_pack = data->options.keep;
530
	args.lock_pack = 1;
531 532
	args.use_thin_pack = data->options.thin;
	args.include_tag = data->options.followtags;
J
Jeff King 已提交
533
	args.verbose = (transport->verbose > 1);
534
	args.quiet = (transport->verbose < 0);
535
	args.no_progress = !transport->progress;
536
	args.depth = data->options.depth;
537 538
	args.check_self_contained_and_connected =
		data->options.check_self_contained_and_connected;
539

I
Ilari Liusvaara 已提交
540
	if (!data->got_remote_heads) {
541
		connect_setup(transport, 0, 0);
542
		get_remote_heads(data->fd[0], NULL, 0, &refs_tmp, 0, NULL);
I
Ilari Liusvaara 已提交
543
		data->got_remote_heads = 1;
544 545
	}

546 547
	refs = fetch_pack(&args, data->fd, data->conn,
			  refs_tmp ? refs_tmp : transport->remote_refs,
548 549
			  dest, to_fetch, nr_heads,
			  &transport->pack_lockfile);
550 551 552 553 554
	close(data->fd[0]);
	close(data->fd[1]);
	if (finish_connect(data->conn))
		refs = NULL;
	data->conn = NULL;
I
Ilari Liusvaara 已提交
555
	data->got_remote_heads = 0;
556 557
	data->options.self_contained_and_connected =
		args.self_contained_and_connected;
558

559 560
	free_refs(refs_tmp);

561
	free(dest);
562
	return (refs ? 0 : -1);
563 564
}

565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
static int push_had_errors(struct ref *ref)
{
	for (; ref; ref = ref->next) {
		switch (ref->status) {
		case REF_STATUS_NONE:
		case REF_STATUS_UPTODATE:
		case REF_STATUS_OK:
			break;
		default:
			return 1;
		}
	}
	return 0;
}

580
int transport_refs_pushed(struct ref *ref)
581 582 583 584 585 586 587 588 589 590 591 592 593
{
	for (; ref; ref = ref->next) {
		switch(ref->status) {
		case REF_STATUS_NONE:
		case REF_STATUS_UPTODATE:
			break;
		default:
			return 1;
		}
	}
	return 0;
}

594
void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int verbose)
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615
{
	struct refspec rs;

	if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
		return;

	rs.src = ref->name;
	rs.dst = NULL;

	if (!remote_find_tracking(remote, &rs)) {
		if (verbose)
			fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
		if (ref->deletion) {
			delete_ref(rs.dst, NULL, 0);
		} else
			update_ref("update by push", rs.dst,
					ref->new_sha1, NULL, 0, 0);
		free(rs.dst);
	}
}

616
static void print_ref_status(char flag, const char *summary, struct ref *to, struct ref *from, const char *msg, int porcelain)
617
{
618 619 620 621 622 623 624 625 626 627
	if (porcelain) {
		if (from)
			fprintf(stdout, "%c\t%s:%s\t", flag, from->name, to->name);
		else
			fprintf(stdout, "%c\t:%s\t", flag, to->name);
		if (msg)
			fprintf(stdout, "%s (%s)\n", summary, msg);
		else
			fprintf(stdout, "%s\n", summary);
	} else {
628
		fprintf(stderr, " %c %-*s ", flag, TRANSPORT_SUMMARY_WIDTH, summary);
629 630 631 632 633 634 635 636 637 638
		if (from)
			fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name));
		else
			fputs(prettify_refname(to->name), stderr);
		if (msg) {
			fputs(" (", stderr);
			fputs(msg, stderr);
			fputc(')', stderr);
		}
		fputc('\n', stderr);
639 640 641 642 643 644 645 646
	}
}

static const char *status_abbrev(unsigned char sha1[20])
{
	return find_unique_abbrev(sha1, DEFAULT_ABBREV);
}

647
static void print_ok_ref_status(struct ref *ref, int porcelain)
648 649
{
	if (ref->deletion)
650
		print_ref_status('-', "[deleted]", ref, NULL, NULL, porcelain);
651 652 653
	else if (is_null_sha1(ref->old_sha1))
		print_ref_status('*',
			(!prefixcmp(ref->name, "refs/tags/") ? "[new tag]" :
654 655
			"[new branch]"),
			ref, ref->peer_ref, NULL, porcelain);
656 657 658 659 660 661
	else {
		char quickref[84];
		char type;
		const char *msg;

		strcpy(quickref, status_abbrev(ref->old_sha1));
662
		if (ref->forced_update) {
663 664 665 666 667 668 669 670 671 672
			strcat(quickref, "...");
			type = '+';
			msg = "forced update";
		} else {
			strcat(quickref, "..");
			type = ' ';
			msg = NULL;
		}
		strcat(quickref, status_abbrev(ref->new_sha1));

673
		print_ref_status(type, quickref, ref, ref->peer_ref, msg, porcelain);
674 675 676
	}
}

677
static int print_one_push_status(struct ref *ref, const char *dest, int count, int porcelain)
678 679
{
	if (!count)
680
		fprintf(porcelain ? stdout : stderr, "To %s\n", dest);
681 682 683

	switch(ref->status) {
	case REF_STATUS_NONE:
684
		print_ref_status('X', "[no match]", ref, NULL, NULL, porcelain);
685 686 687
		break;
	case REF_STATUS_REJECT_NODELETE:
		print_ref_status('!', "[rejected]", ref, NULL,
688
						 "remote does not support deleting refs", porcelain);
689 690 691
		break;
	case REF_STATUS_UPTODATE:
		print_ref_status('=', "[up to date]", ref,
692
						 ref->peer_ref, NULL, porcelain);
693 694 695
		break;
	case REF_STATUS_REJECT_NONFASTFORWARD:
		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
696
						 "non-fast-forward", porcelain);
697
		break;
698 699 700 701
	case REF_STATUS_REJECT_ALREADY_EXISTS:
		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
						 "already exists", porcelain);
		break;
702 703 704 705 706 707 708 709
	case REF_STATUS_REJECT_FETCH_FIRST:
		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
						 "fetch first", porcelain);
		break;
	case REF_STATUS_REJECT_NEEDS_FORCE:
		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
						 "needs force", porcelain);
		break;
710 711
	case REF_STATUS_REMOTE_REJECT:
		print_ref_status('!', "[remote rejected]", ref,
712 713
						 ref->deletion ? NULL : ref->peer_ref,
						 ref->remote_status, porcelain);
714 715 716
		break;
	case REF_STATUS_EXPECTING_REPORT:
		print_ref_status('!', "[remote failure]", ref,
717 718
						 ref->deletion ? NULL : ref->peer_ref,
						 "remote failed to report status", porcelain);
719 720
		break;
	case REF_STATUS_OK:
721
		print_ok_ref_status(ref, porcelain);
722 723 724 725 726 727
		break;
	}

	return 1;
}

728
void transport_print_push_status(const char *dest, struct ref *refs,
729
				  int verbose, int porcelain, unsigned int *reject_reasons)
730 731 732
{
	struct ref *ref;
	int n = 0;
733 734 735 736
	unsigned char head_sha1[20];
	char *head;

	head = resolve_refdup("HEAD", head_sha1, 1, NULL);
737 738 739 740

	if (verbose) {
		for (ref = refs; ref; ref = ref->next)
			if (ref->status == REF_STATUS_UPTODATE)
741
				n += print_one_push_status(ref, dest, n, porcelain);
742 743 744 745
	}

	for (ref = refs; ref; ref = ref->next)
		if (ref->status == REF_STATUS_OK)
746
			n += print_one_push_status(ref, dest, n, porcelain);
747

748
	*reject_reasons = 0;
749 750 751 752
	for (ref = refs; ref; ref = ref->next) {
		if (ref->status != REF_STATUS_NONE &&
		    ref->status != REF_STATUS_UPTODATE &&
		    ref->status != REF_STATUS_OK)
753
			n += print_one_push_status(ref, dest, n, porcelain);
754
		if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD) {
755
			if (head != NULL && !strcmp(head, ref->name))
756
				*reject_reasons |= REJECT_NON_FF_HEAD;
757
			else
758
				*reject_reasons |= REJECT_NON_FF_OTHER;
759 760
		} else if (ref->status == REF_STATUS_REJECT_ALREADY_EXISTS) {
			*reject_reasons |= REJECT_ALREADY_EXISTS;
761 762 763 764
		} else if (ref->status == REF_STATUS_REJECT_FETCH_FIRST) {
			*reject_reasons |= REJECT_FETCH_FIRST;
		} else if (ref->status == REF_STATUS_REJECT_NEEDS_FORCE) {
			*reject_reasons |= REJECT_NEEDS_FORCE;
765
		}
766 767 768
	}
}

769
void transport_verify_remote_names(int nr_heads, const char **heads)
770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
{
	int i;

	for (i = 0; i < nr_heads; i++) {
		const char *local = heads[i];
		const char *remote = strrchr(heads[i], ':');

		if (*local == '+')
			local++;

		/* A matching refspec is okay.  */
		if (remote == local && remote[1] == '\0')
			continue;

		remote = remote ? (remote + 1) : local;
785 786 787 788
		if (check_refname_format(remote,
				REFNAME_ALLOW_ONELEVEL|REFNAME_REFSPEC_PATTERN))
			die("remote part of refspec is not a valid name in %s",
				heads[i]);
789 790 791 792
	}
}

static int git_transport_push(struct transport *transport, struct ref *remote_refs, int flags)
793
{
794
	struct git_transport_data *data = transport->data;
D
Daniel Barkalow 已提交
795
	struct send_pack_args args;
796 797
	int ret;

I
Ilari Liusvaara 已提交
798
	if (!data->got_remote_heads) {
799 800 801
		struct ref *tmp_refs;
		connect_setup(transport, 1, 0);

802
		get_remote_heads(data->fd[0], NULL, 0, &tmp_refs, REF_NORMAL, NULL);
I
Ilari Liusvaara 已提交
803
		data->got_remote_heads = 1;
804
	}
805

806
	memset(&args, 0, sizeof(args));
A
Andy Whitcroft 已提交
807
	args.send_mirror = !!(flags & TRANSPORT_PUSH_MIRROR);
D
Daniel Barkalow 已提交
808
	args.force_update = !!(flags & TRANSPORT_PUSH_FORCE);
809
	args.use_thin_pack = data->options.thin;
810 811
	args.verbose = (transport->verbose > 0);
	args.quiet = (transport->verbose < 0);
812
	args.progress = transport->progress;
D
Daniel Barkalow 已提交
813
	args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
814
	args.porcelain = !!(flags & TRANSPORT_PUSH_PORCELAIN);
D
Daniel Barkalow 已提交
815

816 817 818 819 820 821 822
	ret = send_pack(&args, data->fd, data->conn, remote_refs,
			&data->extra_have);

	close(data->fd[1]);
	close(data->fd[0]);
	ret |= finish_connect(data->conn);
	data->conn = NULL;
I
Ilari Liusvaara 已提交
823
	data->got_remote_heads = 0;
824 825

	return ret;
826 827
}

828 829 830 831 832 833 834 835 836 837 838
static int connect_git(struct transport *transport, const char *name,
		       const char *executable, int fd[2])
{
	struct git_transport_data *data = transport->data;
	data->conn = git_connect(data->fd, transport->url,
				 executable, 0);
	fd[0] = data->fd[0];
	fd[1] = data->fd[1];
	return 0;
}

839 840
static int disconnect_git(struct transport *transport)
{
841 842
	struct git_transport_data *data = transport->data;
	if (data->conn) {
I
Ilari Liusvaara 已提交
843 844
		if (data->got_remote_heads)
			packet_flush(data->fd[1]);
845 846 847 848 849 850
		close(data->fd[0]);
		close(data->fd[1]);
		finish_connect(data->conn);
	}

	free(data);
851 852 853
	return 0;
}

I
Ilari Liusvaara 已提交
854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879
void transport_take_over(struct transport *transport,
			 struct child_process *child)
{
	struct git_transport_data *data;

	if (!transport->smart_options)
		die("Bug detected: Taking over transport requires non-NULL "
		    "smart_options field.");

	data = xcalloc(1, sizeof(*data));
	data->options = *transport->smart_options;
	data->conn = child;
	data->fd[0] = data->conn->out;
	data->fd[1] = data->conn->in;
	data->got_remote_heads = 0;
	transport->data = data;

	transport->set_option = NULL;
	transport->get_refs_list = get_refs_via_connect;
	transport->fetch = fetch_refs_via_pack;
	transport->push = NULL;
	transport->push_refs = git_transport_push;
	transport->disconnect = disconnect_git;
	transport->smart_options = &(data->options);
}

880 881 882 883
static int is_local(const char *url)
{
	const char *colon = strchr(url, ':');
	const char *slash = strchr(url, '/');
884 885
	return !colon || (slash && slash < colon) ||
		has_dos_drive_prefix(url);
886 887 888 889 890 891 892 893 894 895
}

static int is_file(const char *url)
{
	struct stat buf;
	if (stat(url, &buf))
		return 0;
	return S_ISREG(buf.st_mode);
}

896 897 898 899 900
static int external_specification_len(const char *url)
{
	return strchr(url, ':') - url;
}

901
struct transport *transport_get(struct remote *remote, const char *url)
902
{
I
Ilari Liusvaara 已提交
903
	const char *helper;
904 905
	struct transport *ret = xcalloc(1, sizeof(*ret));

906 907
	ret->progress = isatty(2);

908 909 910
	if (!remote)
		die("No remote provided to transport_get()");

911
	ret->got_remote_refs = 0;
912
	ret->remote = remote;
I
Ilari Liusvaara 已提交
913
	helper = remote->foreign_vcs;
914

915
	if (!url && remote->url)
916
		url = remote->url[0];
917 918
	ret->url = url;

919 920 921 922
	/* maybe it is a foreign URL? */
	if (url) {
		const char *p = url;

J
Jeff King 已提交
923
		while (is_urlschemechar(p == url, *p))
924 925
			p++;
		if (!prefixcmp(p, "::"))
I
Ilari Liusvaara 已提交
926
			helper = xstrndup(url, p - url);
927 928
	}

I
Ilari Liusvaara 已提交
929 930
	if (helper) {
		transport_helper_init(ret, helper);
931
	} else if (!prefixcmp(url, "rsync:")) {
932 933 934
		ret->get_refs_list = get_refs_via_rsync;
		ret->fetch = fetch_objs_via_rsync;
		ret->push = rsync_transport_push;
935
		ret->smart_options = NULL;
936
	} else if (is_local(url) && is_file(url) && is_bundle(url, 1)) {
J
Johannes Schindelin 已提交
937 938
		struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
		ret->data = data;
939 940 941
		ret->get_refs_list = get_refs_from_bundle;
		ret->fetch = fetch_refs_from_bundle;
		ret->disconnect = close_bundle;
942
		ret->smart_options = NULL;
943 944 945 946 947 948 949
	} else if (!is_url(url)
		|| !prefixcmp(url, "file://")
		|| !prefixcmp(url, "git://")
		|| !prefixcmp(url, "ssh://")
		|| !prefixcmp(url, "git+ssh://")
		|| !prefixcmp(url, "ssh+git://")) {
		/* These are builtin smart transports. */
950 951
		struct git_transport_data *data = xcalloc(1, sizeof(*data));
		ret->data = data;
952
		ret->set_option = NULL;
953 954
		ret->get_refs_list = get_refs_via_connect;
		ret->fetch = fetch_refs_via_pack;
955
		ret->push_refs = git_transport_push;
956
		ret->connect = connect_git;
957
		ret->disconnect = disconnect_git;
958
		ret->smart_options = &(data->options);
959

960
		data->conn = NULL;
I
Ilari Liusvaara 已提交
961
		data->got_remote_heads = 0;
962 963 964 965 966 967 968
	} else {
		/* Unknown protocol in URL. Pass to external handler. */
		int len = external_specification_len(url);
		char *handler = xmalloc(len + 1);
		handler[len] = 0;
		strncpy(handler, url, len);
		transport_helper_init(ret, handler);
969
	}
970

971 972 973 974 975 976 977 978 979 980
	if (ret->smart_options) {
		ret->smart_options->thin = 1;
		ret->smart_options->uploadpack = "git-upload-pack";
		if (remote->uploadpack)
			ret->smart_options->uploadpack = remote->uploadpack;
		ret->smart_options->receivepack = "git-receive-pack";
		if (remote->receivepack)
			ret->smart_options->receivepack = remote->receivepack;
	}

981 982 983 984 985 986
	return ret;
}

int transport_set_option(struct transport *transport,
			 const char *name, const char *value)
{
987 988 989 990 991 992
	int git_reports = 1, protocol_reports = 1;

	if (transport->smart_options)
		git_reports = set_git_option(transport->smart_options,
					     name, value);

993
	if (transport->set_option)
994 995 996 997 998 999 1000 1001 1002 1003
		protocol_reports = transport->set_option(transport, name,
							value);

	/* If either report is 0, report 0 (success). */
	if (!git_reports || !protocol_reports)
		return 0;
	/* If either reports -1 (invalid value), report -1. */
	if ((git_reports == -1) || (protocol_reports == -1))
		return -1;
	/* Otherwise if both report unknown, report unknown. */
1004
	return 1;
1005 1006
}

1007 1008
void transport_set_verbosity(struct transport *transport, int verbosity,
	int force_progress)
1009
{
J
Jeff King 已提交
1010
	if (verbosity >= 1)
1011 1012 1013
		transport->verbose = verbosity <= 3 ? verbosity : 3;
	if (verbosity < 0)
		transport->verbose = -1;
1014 1015 1016 1017 1018

	/**
	 * Rules used to determine whether to report progress (processing aborts
	 * when a rule is satisfied):
	 *
1019 1020 1021 1022
	 *   . Report progress, if force_progress is 1 (ie. --progress).
	 *   . Don't report progress, if force_progress is 0 (ie. --no-progress).
	 *   . Don't report progress, if verbosity < 0 (ie. -q/--quiet ).
	 *   . Report progress if isatty(2) is 1.
1023
	 **/
1024 1025 1026 1027
	if (force_progress >= 0)
		transport->progress = !!force_progress;
	else
		transport->progress = verbosity >= 0 && isatty(2);
1028 1029
}

1030 1031 1032 1033 1034 1035 1036 1037
static void die_with_unpushed_submodules(struct string_list *needs_pushing)
{
	int i;

	fprintf(stderr, "The following submodule paths contain changes that can\n"
			"not be found on any remote:\n");
	for (i = 0; i < needs_pushing->nr; i++)
		printf("  %s\n", needs_pushing->items[i].string);
1038 1039 1040 1041 1042
	fprintf(stderr, "\nPlease try\n\n"
			"	git push --recurse-submodules=on-demand\n\n"
			"or cd to the path and use\n\n"
			"	git push\n\n"
			"to push them to a remote.\n\n");
1043 1044 1045 1046 1047 1048

	string_list_clear(needs_pushing, 0);

	die("Aborting.");
}

1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104
static int run_pre_push_hook(struct transport *transport,
			     struct ref *remote_refs)
{
	int ret = 0, x;
	struct ref *r;
	struct child_process proc;
	struct strbuf buf;
	const char *argv[4];

	if (!(argv[0] = find_hook("pre-push")))
		return 0;

	argv[1] = transport->remote->name;
	argv[2] = transport->url;
	argv[3] = NULL;

	memset(&proc, 0, sizeof(proc));
	proc.argv = argv;
	proc.in = -1;

	if (start_command(&proc)) {
		finish_command(&proc);
		return -1;
	}

	strbuf_init(&buf, 256);

	for (r = remote_refs; r; r = r->next) {
		if (!r->peer_ref) continue;
		if (r->status == REF_STATUS_REJECT_NONFASTFORWARD) continue;
		if (r->status == REF_STATUS_UPTODATE) continue;

		strbuf_reset(&buf);
		strbuf_addf( &buf, "%s %s %s %s\n",
			 r->peer_ref->name, sha1_to_hex(r->new_sha1),
			 r->name, sha1_to_hex(r->old_sha1));

		if (write_in_full(proc.in, buf.buf, buf.len) != buf.len) {
			ret = -1;
			break;
		}
	}

	strbuf_release(&buf);

	x = close(proc.in);
	if (!ret)
		ret = x;

	x = finish_command(&proc);
	if (!ret)
		ret = x;

	return ret;
}

1105
int transport_push(struct transport *transport,
1106
		   int refspec_nr, const char **refspec, int flags,
1107
		   unsigned int *reject_reasons)
1108
{
1109
	*reject_reasons = 0;
1110
	transport_verify_remote_names(refspec_nr, refspec);
1111

I
Ilari Liusvaara 已提交
1112
	if (transport->push) {
I
Ilari Liusvaara 已提交
1113 1114 1115 1116
		/* Maybe FIXME. But no important transport uses this case. */
		if (flags & TRANSPORT_PUSH_SET_UPSTREAM)
			die("This transport does not support using --set-upstream");

1117
		return transport->push(transport, refspec_nr, refspec, flags);
I
Ilari Liusvaara 已提交
1118
	} else if (transport->push_refs) {
1119 1120 1121 1122
		struct ref *remote_refs =
			transport->get_refs_list(transport, 1);
		struct ref *local_refs = get_local_heads();
		int match_flags = MATCH_REFS_NONE;
1123 1124
		int verbose = (transport->verbose > 0);
		int quiet = (transport->verbose < 0);
1125
		int porcelain = flags & TRANSPORT_PUSH_PORCELAIN;
I
Ilari Liusvaara 已提交
1126
		int pretend = flags & TRANSPORT_PUSH_DRY_RUN;
1127
		int push_ret, ret, err;
1128 1129 1130 1131 1132

		if (flags & TRANSPORT_PUSH_ALL)
			match_flags |= MATCH_REFS_ALL;
		if (flags & TRANSPORT_PUSH_MIRROR)
			match_flags |= MATCH_REFS_MIRROR;
F
Felipe Contreras 已提交
1133 1134
		if (flags & TRANSPORT_PUSH_PRUNE)
			match_flags |= MATCH_REFS_PRUNE;
J
Junio C Hamano 已提交
1135 1136
		if (flags & TRANSPORT_PUSH_FOLLOW_TAGS)
			match_flags |= MATCH_REFS_FOLLOW_TAGS;
1137

1138 1139
		if (match_push_refs(local_refs, &remote_refs,
				    refspec_nr, refspec, match_flags)) {
1140 1141 1142
			return -1;
		}

1143 1144 1145 1146
		set_ref_status_for_push(remote_refs,
			flags & TRANSPORT_PUSH_MIRROR,
			flags & TRANSPORT_PUSH_FORCE);

1147 1148 1149 1150
		if (!(flags & TRANSPORT_PUSH_NO_HOOK))
			if (run_pre_push_hook(transport, remote_refs))
				return -1;

1151
		if ((flags & TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND) && !is_bare_repository()) {
1152 1153 1154
			struct ref *ref = remote_refs;
			for (; ref; ref = ref->next)
				if (!is_null_sha1(ref->new_sha1) &&
1155 1156 1157 1158 1159 1160 1161
				    !push_unpushed_submodules(ref->new_sha1,
					    transport->remote->name))
				    die ("Failed to push all needed submodules!");
		}

		if ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND |
			      TRANSPORT_RECURSE_SUBMODULES_CHECK)) && !is_bare_repository()) {
1162
			struct ref *ref = remote_refs;
1163 1164 1165 1166
			struct string_list needs_pushing;

			memset(&needs_pushing, 0, sizeof(struct string_list));
			needs_pushing.strdup_strings = 1;
1167 1168
			for (; ref; ref = ref->next)
				if (!is_null_sha1(ref->new_sha1) &&
1169 1170 1171
				    find_unpushed_submodules(ref->new_sha1,
					    transport->remote->name, &needs_pushing))
					die_with_unpushed_submodules(&needs_pushing);
1172 1173
		}

1174
		push_ret = transport->push_refs(transport, remote_refs, flags);
1175
		err = push_had_errors(remote_refs);
1176
		ret = push_ret | err;
1177

1178
		if (!quiet || err)
1179
			transport_print_push_status(transport->url, remote_refs,
J
Junio C Hamano 已提交
1180
					verbose | porcelain, porcelain,
1181
					reject_reasons);
1182

I
Ilari Liusvaara 已提交
1183 1184 1185
		if (flags & TRANSPORT_PUSH_SET_UPSTREAM)
			set_upstreams(transport, remote_refs, pretend);

1186 1187 1188
		if (!(flags & TRANSPORT_PUSH_DRY_RUN)) {
			struct ref *ref;
			for (ref = remote_refs; ref; ref = ref->next)
1189
				transport_update_tracking_ref(transport->remote, ref, verbose);
1190 1191
		}

1192 1193
		if (porcelain && !push_ret)
			puts("Done");
1194
		else if (!quiet && !ret && !transport_refs_pushed(remote_refs))
1195
			fprintf(stderr, "Everything up-to-date\n");
1196

1197 1198 1199
		return ret;
	}
	return 1;
1200 1201
}

1202
const struct ref *transport_get_remote_refs(struct transport *transport)
1203
{
1204
	if (!transport->got_remote_refs) {
1205
		transport->remote_refs = transport->get_refs_list(transport, 0);
1206 1207
		transport->got_remote_refs = 1;
	}
I
Ilari Liusvaara 已提交
1208

1209 1210 1211
	return transport->remote_refs;
}

D
Daniel Barkalow 已提交
1212
int transport_fetch_refs(struct transport *transport, struct ref *refs)
1213
{
1214
	int rc;
N
Nicolas Pitre 已提交
1215
	int nr_heads = 0, nr_alloc = 0, nr_refs = 0;
D
Daniel Barkalow 已提交
1216 1217
	struct ref **heads = NULL;
	struct ref *rm;
1218 1219

	for (rm = refs; rm; rm = rm->next) {
N
Nicolas Pitre 已提交
1220
		nr_refs++;
1221
		if (rm->peer_ref &&
D
Daniel Barkalow 已提交
1222
		    !is_null_sha1(rm->old_sha1) &&
1223 1224
		    !hashcmp(rm->peer_ref->old_sha1, rm->old_sha1))
			continue;
1225
		ALLOC_GROW(heads, nr_heads + 1, nr_alloc);
1226
		heads[nr_heads++] = rm;
1227 1228
	}

N
Nicolas Pitre 已提交
1229 1230 1231 1232 1233 1234
	if (!nr_heads) {
		/*
		 * When deepening of a shallow repository is requested,
		 * then local and remote refs are likely to still be equal.
		 * Just feed them all to the fetch method in that case.
		 * This condition shouldn't be met in a non-deepening fetch
1235
		 * (see builtin/fetch.c:quickfetch()).
N
Nicolas Pitre 已提交
1236 1237 1238 1239 1240 1241
		 */
		heads = xmalloc(nr_refs * sizeof(*heads));
		for (rm = refs; rm; rm = rm->next)
			heads[nr_heads++] = rm;
	}

1242
	rc = transport->fetch(transport, nr_heads, heads);
I
Ilari Liusvaara 已提交
1243

1244
	free(heads);
1245
	return rc;
1246 1247
}

1248 1249 1250
void transport_unlock_pack(struct transport *transport)
{
	if (transport->pack_lockfile) {
1251
		unlink_or_warn(transport->pack_lockfile);
1252 1253 1254 1255 1256
		free(transport->pack_lockfile);
		transport->pack_lockfile = NULL;
	}
}

1257 1258 1259 1260 1261 1262 1263 1264 1265
int transport_connect(struct transport *transport, const char *name,
		      const char *exec, int fd[2])
{
	if (transport->connect)
		return transport->connect(transport, name, exec, fd);
	else
		die("Operation not supported by protocol");
}

1266 1267 1268
int transport_disconnect(struct transport *transport)
{
	int ret = 0;
1269 1270
	if (transport->disconnect)
		ret = transport->disconnect(transport);
1271 1272 1273
	free(transport);
	return ret;
}
1274 1275

/*
J
Jim Meyering 已提交
1276
 * Strip username (and password) from a URL and return
1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321
 * it in a newly allocated string.
 */
char *transport_anonymize_url(const char *url)
{
	char *anon_url, *scheme_prefix, *anon_part;
	size_t anon_len, prefix_len = 0;

	anon_part = strchr(url, '@');
	if (is_local(url) || !anon_part)
		goto literal_copy;

	anon_len = strlen(++anon_part);
	scheme_prefix = strstr(url, "://");
	if (!scheme_prefix) {
		if (!strchr(anon_part, ':'))
			/* cannot be "me@there:/path/name" */
			goto literal_copy;
	} else {
		const char *cp;
		/* make sure scheme is reasonable */
		for (cp = url; cp < scheme_prefix; cp++) {
			switch (*cp) {
				/* RFC 1738 2.1 */
			case '+': case '.': case '-':
				break; /* ok */
			default:
				if (isalnum(*cp))
					break;
				/* it isn't */
				goto literal_copy;
			}
		}
		/* @ past the first slash does not count */
		cp = strchr(scheme_prefix + 3, '/');
		if (cp && cp < anon_part)
			goto literal_copy;
		prefix_len = scheme_prefix - url + 3;
	}
	anon_url = xcalloc(1, 1 + prefix_len + anon_len);
	memcpy(anon_url, url, prefix_len);
	memcpy(anon_url + prefix_len, anon_part, anon_len);
	return anon_url;
literal_copy:
	return xstrdup(url);
}
1322

1323 1324 1325 1326 1327 1328 1329
struct alternate_refs_data {
	alternate_ref_fn *fn;
	void *data;
};

static int refs_from_alternate_cb(struct alternate_object_database *e,
				  void *data)
1330 1331 1332 1333 1334 1335
{
	char *other;
	size_t len;
	struct remote *remote;
	struct transport *transport;
	const struct ref *extra;
1336
	struct alternate_refs_data *cb = data;
1337 1338

	e->name[-1] = '\0';
1339
	other = xstrdup(real_path(e->base));
1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356
	e->name[-1] = '/';
	len = strlen(other);

	while (other[len-1] == '/')
		other[--len] = '\0';
	if (len < 8 || memcmp(other + len - 8, "/objects", 8))
		return 0;
	/* Is this a git repository with refs? */
	memcpy(other + len - 8, "/refs", 6);
	if (!is_directory(other))
		return 0;
	other[len - 8] = '\0';
	remote = remote_get(other);
	transport = transport_get(remote, other);
	for (extra = transport_get_remote_refs(transport);
	     extra;
	     extra = extra->next)
1357
		cb->fn(extra, cb->data);
1358 1359 1360 1361
	transport_disconnect(transport);
	free(other);
	return 0;
}
1362 1363 1364 1365 1366 1367 1368 1369

void for_each_alternate_ref(alternate_ref_fn fn, void *data)
{
	struct alternate_refs_data cb;
	cb.fn = fn;
	cb.data = data;
	foreach_alt_odb(refs_from_alternate_cb, &cb);
}