builtin-clone.c 15.5 KB
Newer Older
D
Daniel Barkalow 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Builtin "git clone"
 *
 * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>,
 *		 2008 Daniel Barkalow <barkalow@iabervon.org>
 * Based on git-commit.sh by Junio C Hamano and Linus Torvalds
 *
 * Clone a repository into a different directory that does not yet exist.
 */

#include "cache.h"
#include "parse-options.h"
#include "fetch-pack.h"
#include "refs.h"
#include "tree.h"
#include "tree-walk.h"
#include "unpack-trees.h"
#include "transport.h"
#include "strbuf.h"
#include "dir.h"
J
Johan Herland 已提交
21
#include "pack-refs.h"
D
Daniel Barkalow 已提交
22 23 24 25 26 27 28 29 30 31

/*
 * Overall FIXMEs:
 *  - respect DB_ENVIRONMENT for .git/objects.
 *
 * Implementation notes:
 *  - dropping use-separate-remote and no-separate-remote compatibility
 *
 */
static const char * const builtin_clone_usage[] = {
S
Stephan Beyer 已提交
32
	"git clone [options] [--] <repo> [<dir>]",
D
Daniel Barkalow 已提交
33 34 35
	NULL
};

36
static int option_quiet, option_no_checkout, option_bare, option_mirror;
D
Daniel Barkalow 已提交
37 38 39 40
static int option_local, option_no_hardlinks, option_shared;
static char *option_template, *option_reference, *option_depth;
static char *option_origin = NULL;
static char *option_upload_pack = "git-upload-pack";
M
Miklos Vajna 已提交
41
static int option_verbose;
D
Daniel Barkalow 已提交
42 43 44

static struct option builtin_clone_options[] = {
	OPT__QUIET(&option_quiet),
M
Miklos Vajna 已提交
45
	OPT__VERBOSE(&option_verbose),
D
Daniel Barkalow 已提交
46 47 48 49
	OPT_BOOLEAN('n', "no-checkout", &option_no_checkout,
		    "don't create a checkout"),
	OPT_BOOLEAN(0, "bare", &option_bare, "create a bare repository"),
	OPT_BOOLEAN(0, "naked", &option_bare, "create a bare repository"),
50 51
	OPT_BOOLEAN(0, "mirror", &option_mirror,
		    "create a mirror repository (implies bare)"),
D
Daniel Barkalow 已提交
52 53 54 55 56 57 58 59 60 61 62
	OPT_BOOLEAN('l', "local", &option_local,
		    "to clone from a local repository"),
	OPT_BOOLEAN(0, "no-hardlinks", &option_no_hardlinks,
		    "don't use local hardlinks, always copy"),
	OPT_BOOLEAN('s', "shared", &option_shared,
		    "setup as shared repository"),
	OPT_STRING(0, "template", &option_template, "path",
		   "path the template repository"),
	OPT_STRING(0, "reference", &option_reference, "repo",
		   "reference repository"),
	OPT_STRING('o', "origin", &option_origin, "branch",
F
Fabrizio Chiarello 已提交
63
		   "use <branch> instead of 'origin' to track upstream"),
D
Daniel Barkalow 已提交
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
	OPT_STRING('u', "upload-pack", &option_upload_pack, "path",
		   "path to git-upload-pack on the remote"),
	OPT_STRING(0, "depth", &option_depth, "depth",
		    "create a shallow clone of that depth"),

	OPT_END()
};

static char *get_repo_path(const char *repo, int *is_bundle)
{
	static char *suffix[] = { "/.git", ".git", "" };
	static char *bundle_suffix[] = { ".bundle", "" };
	struct stat st;
	int i;

	for (i = 0; i < ARRAY_SIZE(suffix); i++) {
		const char *path;
		path = mkpath("%s%s", repo, suffix[i]);
82
		if (is_directory(path)) {
D
Daniel Barkalow 已提交
83
			*is_bundle = 0;
84
			return xstrdup(make_nonrelative_path(path));
D
Daniel Barkalow 已提交
85 86 87 88 89 90 91 92
		}
	}

	for (i = 0; i < ARRAY_SIZE(bundle_suffix); i++) {
		const char *path;
		path = mkpath("%s%s", repo, bundle_suffix[i]);
		if (!stat(path, &st) && S_ISREG(st.st_mode)) {
			*is_bundle = 1;
93
			return xstrdup(make_nonrelative_path(path));
D
Daniel Barkalow 已提交
94 95 96 97 98 99
		}
	}

	return NULL;
}

100
static char *guess_dir_name(const char *repo, int is_bundle, int is_bare)
D
Daniel Barkalow 已提交
101
{
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
	const char *end = repo + strlen(repo), *start;

	/*
	 * Strip trailing slashes and /.git
	 */
	while (repo < end && is_dir_sep(end[-1]))
		end--;
	if (end - repo > 5 && is_dir_sep(end[-5]) &&
	    !strncmp(end - 4, ".git", 4)) {
		end -= 5;
		while (repo < end && is_dir_sep(end[-1]))
			end--;
	}

	/*
	 * Find last component, but be prepared that repo could have
	 * the form  "remote.example.com:foo.git", i.e. no slash
	 * in the directory part.
	 */
	start = end;
	while (repo < start && !is_dir_sep(start[-1]) && start[-1] != ':')
		start--;

	/*
	 * Strip .{bundle,git}.
	 */
	if (is_bundle) {
		if (end - start > 7 && !strncmp(end - 7, ".bundle", 7))
			end -= 7;
	} else {
		if (end - start > 4 && !strncmp(end - 4, ".git", 4))
			end -= 4;
D
Daniel Barkalow 已提交
134 135
	}

136
	if (is_bare) {
137 138 139
		struct strbuf result = STRBUF_INIT;
		strbuf_addf(&result, "%.*s.git", (int)(end - start), start);
		return strbuf_detach(&result, 0);
140 141
	}

D
Daniel Barkalow 已提交
142 143 144
	return xstrndup(start, end - start);
}

145 146 147 148 149 150 151 152 153
static void strip_trailing_slashes(char *dir)
{
	char *end = dir + strlen(dir);

	while (dir < end - 1 && is_dir_sep(end[-1]))
		end--;
	*end = '\0';
}

D
Daniel Barkalow 已提交
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
static void setup_reference(const char *repo)
{
	const char *ref_git;
	char *ref_git_copy;

	struct remote *remote;
	struct transport *transport;
	const struct ref *extra;

	ref_git = make_absolute_path(option_reference);

	if (is_directory(mkpath("%s/.git/objects", ref_git)))
		ref_git = mkpath("%s/.git", ref_git);
	else if (!is_directory(mkpath("%s/objects", ref_git)))
		die("reference repository '%s' is not a local directory.",
		    option_reference);

	ref_git_copy = xstrdup(ref_git);

	add_to_alternates_file(ref_git_copy);

	remote = remote_get(ref_git_copy);
	transport = transport_get(remote, ref_git_copy);
	for (extra = transport_get_remote_refs(transport); extra;
	     extra = extra->next)
		add_extra_ref(extra->name, extra->old_sha1, 0);

	transport_disconnect(transport);

	free(ref_git_copy);
}

186
static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
D
Daniel Barkalow 已提交
187 188 189 190 191 192
{
	struct dirent *de;
	struct stat buf;
	int src_len, dest_len;
	DIR *dir;

193
	dir = opendir(src->buf);
D
Daniel Barkalow 已提交
194
	if (!dir)
195
		die("failed to open %s", src->buf);
D
Daniel Barkalow 已提交
196

197
	if (mkdir(dest->buf, 0777)) {
D
Daniel Barkalow 已提交
198
		if (errno != EEXIST)
199
			die("failed to create directory %s", dest->buf);
200
		else if (stat(dest->buf, &buf))
201
			die("failed to stat %s", dest->buf);
D
Daniel Barkalow 已提交
202
		else if (!S_ISDIR(buf.st_mode))
203
			die("%s exists and is not a directory", dest->buf);
D
Daniel Barkalow 已提交
204 205
	}

206 207 208 209
	strbuf_addch(src, '/');
	src_len = src->len;
	strbuf_addch(dest, '/');
	dest_len = dest->len;
D
Daniel Barkalow 已提交
210 211

	while ((de = readdir(dir)) != NULL) {
212 213 214 215 216 217
		strbuf_setlen(src, src_len);
		strbuf_addstr(src, de->d_name);
		strbuf_setlen(dest, dest_len);
		strbuf_addstr(dest, de->d_name);
		if (stat(src->buf, &buf)) {
			warning ("failed to stat %s\n", src->buf);
D
Daniel Barkalow 已提交
218 219 220 221 222 223 224 225
			continue;
		}
		if (S_ISDIR(buf.st_mode)) {
			if (de->d_name[0] != '.')
				copy_or_link_directory(src, dest);
			continue;
		}

226
		if (unlink(dest->buf) && errno != ENOENT)
227
			die("failed to unlink %s", dest->buf);
228
		if (!option_no_hardlinks) {
229
			if (!link(src->buf, dest->buf))
230 231
				continue;
			if (option_local)
232
				die("failed to create link %s", dest->buf);
233
			option_no_hardlinks = 1;
D
Daniel Barkalow 已提交
234
		}
235
		if (copy_file(dest->buf, src->buf, 0666))
236
			die("failed to copy file to %s", dest->buf);
D
Daniel Barkalow 已提交
237
	}
238
	closedir(dir);
D
Daniel Barkalow 已提交
239 240 241 242 243 244
}

static const struct ref *clone_local(const char *src_repo,
				     const char *dest_repo)
{
	const struct ref *ret;
245 246
	struct strbuf src = STRBUF_INIT;
	struct strbuf dest = STRBUF_INIT;
D
Daniel Barkalow 已提交
247 248 249 250 251 252
	struct remote *remote;
	struct transport *transport;

	if (option_shared)
		add_to_alternates_file(src_repo);
	else {
253 254 255 256 257
		strbuf_addf(&src, "%s/objects", src_repo);
		strbuf_addf(&dest, "%s/objects", dest_repo);
		copy_or_link_directory(&src, &dest);
		strbuf_release(&src);
		strbuf_release(&dest);
D
Daniel Barkalow 已提交
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
	}

	remote = remote_get(src_repo);
	transport = transport_get(remote, src_repo);
	ret = transport_get_remote_refs(transport);
	transport_disconnect(transport);
	return ret;
}

static const char *junk_work_tree;
static const char *junk_git_dir;
pid_t junk_pid;

static void remove_junk(void)
{
273
	struct strbuf sb = STRBUF_INIT;
D
Daniel Barkalow 已提交
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 338 339
	if (getpid() != junk_pid)
		return;
	if (junk_git_dir) {
		strbuf_addstr(&sb, junk_git_dir);
		remove_dir_recursively(&sb, 0);
		strbuf_reset(&sb);
	}
	if (junk_work_tree) {
		strbuf_addstr(&sb, junk_work_tree);
		remove_dir_recursively(&sb, 0);
		strbuf_reset(&sb);
	}
}

static void remove_junk_on_signal(int signo)
{
	remove_junk();
	signal(SIGINT, SIG_DFL);
	raise(signo);
}

static const struct ref *locate_head(const struct ref *refs,
				     const struct ref *mapped_refs,
				     const struct ref **remote_head_p)
{
	const struct ref *remote_head = NULL;
	const struct ref *remote_master = NULL;
	const struct ref *r;
	for (r = refs; r; r = r->next)
		if (!strcmp(r->name, "HEAD"))
			remote_head = r;

	for (r = mapped_refs; r; r = r->next)
		if (!strcmp(r->name, "refs/heads/master"))
			remote_master = r;

	if (remote_head_p)
		*remote_head_p = remote_head;

	/* If there's no HEAD value at all, never mind. */
	if (!remote_head)
		return NULL;

	/* If refs/heads/master could be right, it is. */
	if (remote_master && !hashcmp(remote_master->old_sha1,
				      remote_head->old_sha1))
		return remote_master;

	/* Look for another ref that points there */
	for (r = mapped_refs; r; r = r->next)
		if (r != remote_head &&
		    !hashcmp(r->old_sha1, remote_head->old_sha1))
			return r;

	/* Nothing is the same */
	return NULL;
}

static struct ref *write_remote_refs(const struct ref *refs,
		struct refspec *refspec, const char *reflog)
{
	struct ref *local_refs = NULL;
	struct ref **tail = &local_refs;
	struct ref *r;

	get_fetch_map(refs, refspec, &tail, 0);
340 341
	if (!option_mirror)
		get_fetch_map(refs, tag_refspec, &tail, 0);
D
Daniel Barkalow 已提交
342 343

	for (r = local_refs; r; r = r->next)
J
Johan Herland 已提交
344 345 346 347 348
		add_extra_ref(r->peer_ref->name, r->old_sha1, 0);

	pack_refs(PACK_REFS_ALL);
	clear_extra_refs();

D
Daniel Barkalow 已提交
349 350 351 352 353 354 355 356 357 358 359 360
	return local_refs;
}

int cmd_clone(int argc, const char **argv, const char *prefix)
{
	int use_local_hardlinks = 1;
	int use_separate_remote = 1;
	int is_bundle = 0;
	struct stat buf;
	const char *repo_name, *repo, *work_tree, *git_dir;
	char *path, *dir;
	const struct ref *refs, *head_points_at, *remote_head, *mapped_refs;
361 362
	struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
	struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
363
	struct transport *transport = NULL;
364
	char *src_ref_prefix = "refs/heads/";
D
Daniel Barkalow 已提交
365 366 367 368 369 370 371 372 373 374 375 376 377 378

	struct refspec refspec;

	junk_pid = getpid();

	argc = parse_options(argc, argv, builtin_clone_options,
			     builtin_clone_usage, 0);

	if (argc == 0)
		die("You must specify a repository to clone.");

	if (option_no_hardlinks)
		use_local_hardlinks = 0;

379 380 381
	if (option_mirror)
		option_bare = 1;

D
Daniel Barkalow 已提交
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
	if (option_bare) {
		if (option_origin)
			die("--bare and --origin %s options are incompatible.",
			    option_origin);
		option_no_checkout = 1;
		use_separate_remote = 0;
	}

	if (!option_origin)
		option_origin = "origin";

	repo_name = argv[0];

	path = get_repo_path(repo_name, &is_bundle);
	if (path)
397
		repo = xstrdup(make_nonrelative_path(repo_name));
D
Daniel Barkalow 已提交
398 399 400 401 402 403 404 405
	else if (!strchr(repo_name, ':'))
		repo = xstrdup(make_absolute_path(repo_name));
	else
		repo = repo_name;

	if (argc == 2)
		dir = xstrdup(argv[1]);
	else
406
		dir = guess_dir_name(repo_name, is_bundle, option_bare);
407
	strip_trailing_slashes(dir);
D
Daniel Barkalow 已提交
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430

	if (!stat(dir, &buf))
		die("destination directory '%s' already exists.", dir);

	strbuf_addf(&reflog_msg, "clone: from %s", repo);

	if (option_bare)
		work_tree = NULL;
	else {
		work_tree = getenv("GIT_WORK_TREE");
		if (work_tree && !stat(work_tree, &buf))
			die("working tree '%s' already exists.", work_tree);
	}

	if (option_bare || work_tree)
		git_dir = xstrdup(dir);
	else {
		work_tree = dir;
		git_dir = xstrdup(mkpath("%s/.git", dir));
	}

	if (!option_bare) {
		junk_work_tree = work_tree;
431
		if (safe_create_leading_directories_const(work_tree) < 0)
432 433
			die("could not create leading directories of '%s': %s",
					work_tree, strerror(errno));
D
Daniel Barkalow 已提交
434
		if (mkdir(work_tree, 0755))
435 436
			die("could not create work tree dir '%s': %s.",
					work_tree, strerror(errno));
D
Daniel Barkalow 已提交
437 438 439 440 441 442 443 444
		set_git_work_tree(work_tree);
	}
	junk_git_dir = git_dir;
	atexit(remove_junk);
	signal(SIGINT, remove_junk_on_signal);

	setenv(CONFIG_ENVIRONMENT, xstrdup(mkpath("%s/config", git_dir)), 1);

445 446
	if (safe_create_leading_directories_const(git_dir) < 0)
		die("could not create leading directories of '%s'", git_dir);
D
Daniel Barkalow 已提交
447 448 449 450
	set_git_dir(make_absolute_path(git_dir));

	init_db(option_template, option_quiet ? INIT_DB_QUIET : 0);

451 452 453 454 455 456 457
	/*
	 * At this point, the config exists, so we do not need the
	 * environment variable.  We actually need to unset it, too, to
	 * re-enable parsing of the global configs.
	 */
	unsetenv(CONFIG_ENVIRONMENT);

D
Daniel Barkalow 已提交
458 459 460
	if (option_reference)
		setup_reference(git_dir);

J
Junio C Hamano 已提交
461
	git_config(git_default_config, NULL);
D
Daniel Barkalow 已提交
462 463

	if (option_bare) {
464 465
		if (option_mirror)
			src_ref_prefix = "refs/";
466
		strbuf_addstr(&branch_top, src_ref_prefix);
D
Daniel Barkalow 已提交
467 468 469

		git_config_set("core.bare", "true");
	} else {
470
		strbuf_addf(&branch_top, "refs/remotes/%s/", option_origin);
471
	}
D
Daniel Barkalow 已提交
472

473
	if (option_mirror || !option_bare) {
D
Daniel Barkalow 已提交
474
		/* Configure the remote */
475
		if (option_mirror) {
476 477 478
			strbuf_addf(&key, "remote.%s.mirror", option_origin);
			git_config_set(key.buf, "true");
			strbuf_reset(&key);
479 480
		}

481 482 483
		strbuf_addf(&key, "remote.%s.url", option_origin);
		git_config_set(key.buf, repo);
			strbuf_reset(&key);
D
Daniel Barkalow 已提交
484

485 486 487 488 489
		strbuf_addf(&key, "remote.%s.fetch", option_origin);
		strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
		git_config_set_multivar(key.buf, value.buf, "^$", 0);
		strbuf_reset(&key);
		strbuf_reset(&value);
D
Daniel Barkalow 已提交
490 491 492 493
	}

	refspec.force = 0;
	refspec.pattern = 1;
494
	refspec.src = src_ref_prefix;
495
	refspec.dst = branch_top.buf;
D
Daniel Barkalow 已提交
496 497 498 499 500

	if (path && !is_bundle)
		refs = clone_local(path, git_dir);
	else {
		struct remote *remote = remote_get(argv[0]);
501
		transport = transport_get(remote, remote->url[0]);
D
Daniel Barkalow 已提交
502

503 504 505
		if (!transport->get_refs_list || !transport->fetch)
			die("Don't know how to clone %s", transport->url);

D
Daniel Barkalow 已提交
506 507 508 509 510 511 512 513
		transport_set_option(transport, TRANS_OPT_KEEP, "yes");

		if (option_depth)
			transport_set_option(transport, TRANS_OPT_DEPTH,
					     option_depth);

		if (option_quiet)
			transport->verbose = -1;
M
Miklos Vajna 已提交
514 515
		else if (option_verbose)
			transport->progress = 1;
D
Daniel Barkalow 已提交
516

517 518 519 520
		if (option_upload_pack)
			transport_set_option(transport, TRANS_OPT_UPLOADPACK,
					     option_upload_pack);

D
Daniel Barkalow 已提交
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535
		refs = transport_get_remote_refs(transport);
		transport_fetch_refs(transport, refs);
	}

	clear_extra_refs();

	mapped_refs = write_remote_refs(refs, &refspec, reflog_msg.buf);

	head_points_at = locate_head(refs, mapped_refs, &remote_head);

	if (head_points_at) {
		/* Local default branch link */
		create_symref("HEAD", head_points_at->name, NULL);

		if (!option_bare) {
536
			struct strbuf head_ref = STRBUF_INIT;
D
Daniel Barkalow 已提交
537 538 539 540 541 542 543 544 545 546 547 548
			const char *head = head_points_at->name;

			if (!prefixcmp(head, "refs/heads/"))
				head += 11;

			/* Set up the initial local branch */

			/* Local branch initial value */
			update_ref(reflog_msg.buf, "HEAD",
				   head_points_at->old_sha1,
				   NULL, 0, DIE_ON_ERR);

549
			strbuf_addstr(&head_ref, branch_top.buf);
D
Daniel Barkalow 已提交
550 551 552 553 554 555 556
			strbuf_addstr(&head_ref, "HEAD");

			/* Remote branch link */
			create_symref(head_ref.buf,
				      head_points_at->peer_ref->name,
				      reflog_msg.buf);

557 558 559 560 561
			strbuf_addf(&key, "branch.%s.remote", head);
			git_config_set(key.buf, option_origin);
			strbuf_reset(&key);
			strbuf_addf(&key, "branch.%s.merge", head);
			git_config_set(key.buf, head_points_at->name);
D
Daniel Barkalow 已提交
562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
		}
	} else if (remote_head) {
		/* Source had detached HEAD pointing somewhere. */
		if (!option_bare)
			update_ref(reflog_msg.buf, "HEAD",
				   remote_head->old_sha1,
				   NULL, REF_NODEREF, DIE_ON_ERR);
	} else {
		/* Nothing to checkout out */
		if (!option_no_checkout)
			warning("remote HEAD refers to nonexistent ref, "
				"unable to checkout.\n");
		option_no_checkout = 1;
	}

577 578 579
	if (transport)
		transport_unlock_pack(transport);

D
Daniel Barkalow 已提交
580 581 582 583 584 585 586 587 588 589 590 591 592 593
	if (!option_no_checkout) {
		struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
		struct unpack_trees_options opts;
		struct tree *tree;
		struct tree_desc t;
		int fd;

		/* We need to be in the new work tree for the checkout */
		setup_work_tree();

		fd = hold_locked_index(lock_file, 1);

		memset(&opts, 0, sizeof opts);
		opts.update = 1;
594 595
		opts.merge = 1;
		opts.fn = oneway_merge;
D
Daniel Barkalow 已提交
596
		opts.verbose_update = !option_quiet;
597
		opts.src_index = &the_index;
D
Daniel Barkalow 已提交
598 599 600 601 602 603 604 605 606 607 608 609 610
		opts.dst_index = &the_index;

		tree = parse_tree_indirect(remote_head->old_sha1);
		parse_tree(tree);
		init_tree_desc(&t, tree->buffer, tree->size);
		unpack_trees(1, &t, &opts);

		if (write_cache(fd, active_cache, active_nr) ||
		    commit_locked_index(lock_file))
			die("unable to write new index file");
	}

	strbuf_release(&reflog_msg);
611 612 613
	strbuf_release(&branch_top);
	strbuf_release(&key);
	strbuf_release(&value);
D
Daniel Barkalow 已提交
614 615 616
	junk_pid = 0;
	return 0;
}