clone.c 20.9 KB
Newer Older
D
Daniel Barkalow 已提交
1 2 3 4 5 6 7 8 9 10
/*
 * 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.
 */

S
Stephen Boyd 已提交
11
#include "builtin.h"
D
Daniel Barkalow 已提交
12 13 14 15 16 17 18 19 20
#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"
22
#include "sigchain.h"
23
#include "branch.h"
J
Jay Soffian 已提交
24
#include "remote.h"
25
#include "run-command.h"
D
Daniel Barkalow 已提交
26 27 28 29 30 31 32 33 34 35

/*
 * 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 已提交
36
	"git clone [options] [--] <repo> [<dir>]",
D
Daniel Barkalow 已提交
37 38 39
	NULL
};

40
static int option_no_checkout, option_bare, option_mirror;
41
static int option_local, option_no_hardlinks, option_shared, option_recursive;
42
static char *option_template, *option_depth;
D
Daniel Barkalow 已提交
43
static char *option_origin = NULL;
44
static char *option_branch = NULL;
45
static const char *real_git_dir;
D
Daniel Barkalow 已提交
46
static char *option_upload_pack = "git-upload-pack";
47
static int option_verbosity;
48
static int option_progress;
49
static struct string_list option_config;
50 51 52 53 54 55 56 57 58 59
static struct string_list option_reference;

static int opt_parse_reference(const struct option *opt, const char *arg, int unset)
{
	struct string_list *option_reference = opt->value;
	if (!arg)
		return -1;
	string_list_append(option_reference, arg);
	return 0;
}
D
Daniel Barkalow 已提交
60 61

static struct option builtin_clone_options[] = {
62
	OPT__VERBOSITY(&option_verbosity),
63 64
	OPT_BOOLEAN(0, "progress", &option_progress,
			"force progress reporting"),
D
Daniel Barkalow 已提交
65 66 67
	OPT_BOOLEAN('n', "no-checkout", &option_no_checkout,
		    "don't create a checkout"),
	OPT_BOOLEAN(0, "bare", &option_bare, "create a bare repository"),
J
Junio C Hamano 已提交
68 69 70
	{ OPTION_BOOLEAN, 0, "naked", &option_bare, NULL,
		"create a bare repository",
		PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
71 72
	OPT_BOOLEAN(0, "mirror", &option_mirror,
		    "create a mirror repository (implies bare)"),
D
Daniel Barkalow 已提交
73 74 75 76 77 78
	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"),
79
	OPT_BOOLEAN(0, "recursive", &option_recursive,
J
Junio C Hamano 已提交
80
		    "initialize submodules in the clone"),
81
	OPT_BOOLEAN(0, "recurse-submodules", &option_recursive,
82
		    "initialize submodules in the clone"),
83 84
	OPT_STRING(0, "template", &option_template, "template-directory",
		   "directory from which templates will be used"),
85 86
	OPT_CALLBACK(0 , "reference", &option_reference, "repo",
		     "reference repository", &opt_parse_reference),
87 88
	OPT_STRING('o', "origin", &option_origin, "name",
		   "use <name> instead of 'origin' to track upstream"),
89 90
	OPT_STRING('b', "branch", &option_branch, "branch",
		   "checkout <branch> instead of the remote's HEAD"),
D
Daniel Barkalow 已提交
91 92 93 94
	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"),
95
	OPT_STRING(0, "separate-git-dir", &real_git_dir, "gitdir",
96
		   "separate git dir from working tree"),
97 98
	OPT_STRING_LIST('c', "config", &option_config, "key=value",
			"set config inside the new repository"),
D
Daniel Barkalow 已提交
99 100 101
	OPT_END()
};

102 103 104 105
static const char *argv_submodule[] = {
	"submodule", "update", "--init", "--recursive", NULL
};

D
Daniel Barkalow 已提交
106 107 108 109 110 111 112 113 114 115
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]);
116 117 118
		if (stat(path, &st))
			continue;
		if (S_ISDIR(st.st_mode)) {
D
Daniel Barkalow 已提交
119
			*is_bundle = 0;
120
			return xstrdup(absolute_path(path));
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
		} else if (S_ISREG(st.st_mode) && st.st_size > 8) {
			/* Is it a "gitfile"? */
			char signature[8];
			int len, fd = open(path, O_RDONLY);
			if (fd < 0)
				continue;
			len = read_in_full(fd, signature, 8);
			close(fd);
			if (len != 8 || strncmp(signature, "gitdir: ", 8))
				continue;
			path = read_gitfile(path);
			if (path) {
				*is_bundle = 0;
				return xstrdup(absolute_path(path));
			}
D
Daniel Barkalow 已提交
136 137 138 139 140 141 142 143
		}
	}

	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;
144
			return xstrdup(absolute_path(path));
D
Daniel Barkalow 已提交
145 146 147 148 149 150
		}
	}

	return NULL;
}

151
static char *guess_dir_name(const char *repo, int is_bundle, int is_bare)
D
Daniel Barkalow 已提交
152
{
153
	const char *end = repo + strlen(repo), *start;
154
	char *dir;
155 156

	/*
157
	 * Strip trailing spaces, slashes and /.git
158
	 */
159
	while (repo < end && (is_dir_sep(end[-1]) || isspace(end[-1])))
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
		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 已提交
186 187
	}

188
	if (is_bare) {
189 190
		struct strbuf result = STRBUF_INIT;
		strbuf_addf(&result, "%.*s.git", (int)(end - start), start);
191
		dir = strbuf_detach(&result, NULL);
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
	} else
		dir = xstrndup(start, end - start);
	/*
	 * Replace sequences of 'control' characters and whitespace
	 * with one ascii space, remove leading and trailing spaces.
	 */
	if (*dir) {
		char *out = dir;
		int prev_space = 1 /* strip leading whitespace */;
		for (end = dir; *end; ++end) {
			char ch = *end;
			if ((unsigned char)ch < '\x20')
				ch = '\x20';
			if (isspace(ch)) {
				if (prev_space)
					continue;
				prev_space = 1;
			} else
				prev_space = 0;
			*out++ = ch;
		}
		*out = '\0';
		if (out > dir && prev_space)
			out[-1] = '\0';
216
	}
217
	return dir;
D
Daniel Barkalow 已提交
218 219
}

220 221 222 223 224 225 226 227 228
static void strip_trailing_slashes(char *dir)
{
	char *end = dir + strlen(dir);

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

229
static int add_one_reference(struct string_list_item *item, void *cb_data)
D
Daniel Barkalow 已提交
230
{
231 232
	char *ref_git;
	struct strbuf alternate = STRBUF_INIT;
D
Daniel Barkalow 已提交
233 234 235 236
	struct remote *remote;
	struct transport *transport;
	const struct ref *extra;

237 238 239 240 241 242 243
	/* Beware: real_path() and mkpath() return static buffer */
	ref_git = xstrdup(real_path(item->string));
	if (is_directory(mkpath("%s/.git/objects", ref_git))) {
		char *ref_git_git = xstrdup(mkpath("%s/.git", ref_git));
		free(ref_git);
		ref_git = ref_git_git;
	} else if (!is_directory(mkpath("%s/objects", ref_git)))
244
		die(_("reference repository '%s' is not a local directory."),
245
		    item->string);
D
Daniel Barkalow 已提交
246

247 248 249
	strbuf_addf(&alternate, "%s/objects", ref_git);
	add_to_alternates_file(alternate.buf);
	strbuf_release(&alternate);
D
Daniel Barkalow 已提交
250

251 252
	remote = remote_get(ref_git);
	transport = transport_get(remote, ref_git);
D
Daniel Barkalow 已提交
253 254 255 256 257
	for (extra = transport_get_remote_refs(transport); extra;
	     extra = extra->next)
		add_extra_ref(extra->name, extra->old_sha1, 0);

	transport_disconnect(transport);
258
	free(ref_git);
259 260
	return 0;
}
D
Daniel Barkalow 已提交
261

262 263 264
static void setup_reference(void)
{
	for_each_string_list(&option_reference, add_one_reference, NULL);
D
Daniel Barkalow 已提交
265 266
}

267 268 269 270 271 272 273 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
static void copy_alternates(struct strbuf *src, struct strbuf *dst,
			    const char *src_repo)
{
	/*
	 * Read from the source objects/info/alternates file
	 * and copy the entries to corresponding file in the
	 * destination repository with add_to_alternates_file().
	 * Both src and dst have "$path/objects/info/alternates".
	 *
	 * Instead of copying bit-for-bit from the original,
	 * we need to append to existing one so that the already
	 * created entry via "clone -s" is not lost, and also
	 * to turn entries with paths relative to the original
	 * absolute, so that they can be used in the new repository.
	 */
	FILE *in = fopen(src->buf, "r");
	struct strbuf line = STRBUF_INIT;

	while (strbuf_getline(&line, in, '\n') != EOF) {
		char *abs_path, abs_buf[PATH_MAX];
		if (!line.len || line.buf[0] == '#')
			continue;
		if (is_absolute_path(line.buf)) {
			add_to_alternates_file(line.buf);
			continue;
		}
		abs_path = mkpath("%s/objects/%s", src_repo, line.buf);
		normalize_path_copy(abs_buf, abs_path);
		add_to_alternates_file(abs_buf);
	}
	strbuf_release(&line);
	fclose(in);
}

static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
				   const char *src_repo, int src_baselen)
D
Daniel Barkalow 已提交
303 304 305 306 307 308
{
	struct dirent *de;
	struct stat buf;
	int src_len, dest_len;
	DIR *dir;

309
	dir = opendir(src->buf);
D
Daniel Barkalow 已提交
310
	if (!dir)
311
		die_errno(_("failed to open '%s'"), src->buf);
D
Daniel Barkalow 已提交
312

313
	if (mkdir(dest->buf, 0777)) {
D
Daniel Barkalow 已提交
314
		if (errno != EEXIST)
315
			die_errno(_("failed to create directory '%s'"), dest->buf);
316
		else if (stat(dest->buf, &buf))
317
			die_errno(_("failed to stat '%s'"), dest->buf);
D
Daniel Barkalow 已提交
318
		else if (!S_ISDIR(buf.st_mode))
319
			die(_("%s exists and is not a directory"), dest->buf);
D
Daniel Barkalow 已提交
320 321
	}

322 323 324 325
	strbuf_addch(src, '/');
	src_len = src->len;
	strbuf_addch(dest, '/');
	dest_len = dest->len;
D
Daniel Barkalow 已提交
326 327

	while ((de = readdir(dir)) != NULL) {
328 329 330 331 332
		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)) {
333
			warning (_("failed to stat %s\n"), src->buf);
D
Daniel Barkalow 已提交
334 335 336 337
			continue;
		}
		if (S_ISDIR(buf.st_mode)) {
			if (de->d_name[0] != '.')
338 339 340 341 342 343 344 345
				copy_or_link_directory(src, dest,
						       src_repo, src_baselen);
			continue;
		}

		/* Files that cannot be copied bit-for-bit... */
		if (!strcmp(src->buf + src_baselen, "/info/alternates")) {
			copy_alternates(src, dest, src_repo);
D
Daniel Barkalow 已提交
346 347 348
			continue;
		}

349
		if (unlink(dest->buf) && errno != ENOENT)
350
			die_errno(_("failed to unlink '%s'"), dest->buf);
351
		if (!option_no_hardlinks) {
352
			if (!link(src->buf, dest->buf))
353 354
				continue;
			if (option_local)
355
				die_errno(_("failed to create link '%s'"), dest->buf);
356
			option_no_hardlinks = 1;
D
Daniel Barkalow 已提交
357
		}
358
		if (copy_file_with_time(dest->buf, src->buf, 0666))
359
			die_errno(_("failed to copy file to '%s'"), dest->buf);
D
Daniel Barkalow 已提交
360
	}
361
	closedir(dir);
D
Daniel Barkalow 已提交
362 363 364 365 366 367 368 369 370
}

static const struct ref *clone_local(const char *src_repo,
				     const char *dest_repo)
{
	const struct ref *ret;
	struct remote *remote;
	struct transport *transport;

371 372 373 374 375 376 377 378
	if (option_shared) {
		struct strbuf alt = STRBUF_INIT;
		strbuf_addf(&alt, "%s/objects", src_repo);
		add_to_alternates_file(alt.buf);
		strbuf_release(&alt);
	} else {
		struct strbuf src = STRBUF_INIT;
		struct strbuf dest = STRBUF_INIT;
379 380
		strbuf_addf(&src, "%s/objects", src_repo);
		strbuf_addf(&dest, "%s/objects", dest_repo);
381
		copy_or_link_directory(&src, &dest, src_repo, src.len);
382 383
		strbuf_release(&src);
		strbuf_release(&dest);
D
Daniel Barkalow 已提交
384 385 386 387 388 389
	}

	remote = remote_get(src_repo);
	transport = transport_get(remote, src_repo);
	ret = transport_get_remote_refs(transport);
	transport_disconnect(transport);
390
	if (0 <= option_verbosity)
391
		printf(_("done.\n"));
D
Daniel Barkalow 已提交
392 393 394 395 396
	return ret;
}

static const char *junk_work_tree;
static const char *junk_git_dir;
397
static pid_t junk_pid;
D
Daniel Barkalow 已提交
398 399 400

static void remove_junk(void)
{
401
	struct strbuf sb = STRBUF_INIT;
D
Daniel Barkalow 已提交
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418
	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();
419
	sigchain_pop(signo);
D
Daniel Barkalow 已提交
420 421 422
	raise(signo);
}

423 424
static struct ref *wanted_peer_refs(const struct ref *refs,
		struct refspec *refspec)
D
Daniel Barkalow 已提交
425
{
J
Jeff King 已提交
426 427 428
	struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD"));
	struct ref *local_refs = head;
	struct ref **tail = head ? &head->next : &local_refs;
D
Daniel Barkalow 已提交
429 430

	get_fetch_map(refs, refspec, &tail, 0);
431 432
	if (!option_mirror)
		get_fetch_map(refs, tag_refspec, &tail, 0);
D
Daniel Barkalow 已提交
433

434 435 436 437 438 439 440
	return local_refs;
}

static void write_remote_refs(const struct ref *local_refs)
{
	const struct ref *r;

J
Jeff King 已提交
441 442 443
	for (r = local_refs; r; r = r->next) {
		if (!r->peer_ref)
			continue;
J
Johan Herland 已提交
444
		add_extra_ref(r->peer_ref->name, r->old_sha1, 0);
J
Jeff King 已提交
445
	}
J
Johan Herland 已提交
446 447 448

	pack_refs(PACK_REFS_ALL);
	clear_extra_refs();
D
Daniel Barkalow 已提交
449 450
}

451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
static int write_one_config(const char *key, const char *value, void *data)
{
	return git_config_set_multivar(key, value ? value : "true", "^$", 0);
}

static void write_config(struct string_list *config)
{
	int i;

	for (i = 0; i < config->nr; i++) {
		if (git_config_parse_parameter(config->items[i].string,
					       write_one_config, NULL) < 0)
			die("unable to write parameters to config file");
	}
}

D
Daniel Barkalow 已提交
467 468
int cmd_clone(int argc, const char **argv, const char *prefix)
{
469
	int is_bundle = 0, is_local;
D
Daniel Barkalow 已提交
470 471 472
	struct stat buf;
	const char *repo_name, *repo, *work_tree, *git_dir;
	char *path, *dir;
473
	int dest_exists;
D
Daniel Barkalow 已提交
474
	const struct ref *refs, *remote_head;
475 476
	const struct ref *remote_head_points_at;
	const struct ref *our_head_points_at;
D
Daniel Barkalow 已提交
477
	struct ref *mapped_refs;
478 479
	struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
	struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
480
	struct transport *transport = NULL;
481
	char *src_ref_prefix = "refs/heads/";
482
	int err = 0;
D
Daniel Barkalow 已提交
483

484 485
	struct refspec *refspec;
	const char *fetch_pattern;
D
Daniel Barkalow 已提交
486 487 488

	junk_pid = getpid();

J
Jeff King 已提交
489
	packet_trace_identity("clone");
490
	argc = parse_options(argc, argv, prefix, builtin_clone_options,
D
Daniel Barkalow 已提交
491 492
			     builtin_clone_usage, 0);

J
Jonathan Nieder 已提交
493
	if (argc > 2)
494
		usage_msg_opt(_("Too many arguments."),
J
Jonathan Nieder 已提交
495 496
			builtin_clone_usage, builtin_clone_options);

D
Daniel Barkalow 已提交
497
	if (argc == 0)
498
		usage_msg_opt(_("You must specify a repository to clone."),
J
Jonathan Nieder 已提交
499
			builtin_clone_usage, builtin_clone_options);
D
Daniel Barkalow 已提交
500

501 502 503
	if (option_mirror)
		option_bare = 1;

D
Daniel Barkalow 已提交
504 505
	if (option_bare) {
		if (option_origin)
506
			die(_("--bare and --origin %s options are incompatible."),
D
Daniel Barkalow 已提交
507 508 509 510 511 512 513 514 515 516 517
			    option_origin);
		option_no_checkout = 1;
	}

	if (!option_origin)
		option_origin = "origin";

	repo_name = argv[0];

	path = get_repo_path(repo_name, &is_bundle);
	if (path)
518
		repo = xstrdup(absolute_path(repo_name));
D
Daniel Barkalow 已提交
519
	else if (!strchr(repo_name, ':'))
520
		die(_("repository '%s' does not exist"), repo_name);
D
Daniel Barkalow 已提交
521 522
	else
		repo = repo_name;
523 524
	is_local = path && !is_bundle;
	if (is_local && option_depth)
525
		warning(_("--depth is ignored in local clones; use file:// instead."));
D
Daniel Barkalow 已提交
526 527 528 529

	if (argc == 2)
		dir = xstrdup(argv[1]);
	else
530
		dir = guess_dir_name(repo_name, is_bundle, option_bare);
531
	strip_trailing_slashes(dir);
D
Daniel Barkalow 已提交
532

533 534
	dest_exists = !stat(dir, &buf);
	if (dest_exists && !is_empty_dir(dir))
535 536
		die(_("destination path '%s' already exists and is not "
			"an empty directory."), dir);
D
Daniel Barkalow 已提交
537 538 539 540 541 542 543 544

	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))
545
			die(_("working tree '%s' already exists."), work_tree);
D
Daniel Barkalow 已提交
546 547 548 549 550 551 552 553 554 555 556
	}

	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;
557
		if (safe_create_leading_directories_const(work_tree) < 0)
558
			die_errno(_("could not create leading directories of '%s'"),
559
				  work_tree);
560
		if (!dest_exists && mkdir(work_tree, 0755))
561
			die_errno(_("could not create work tree dir '%s'."),
562
				  work_tree);
D
Daniel Barkalow 已提交
563 564 565 566
		set_git_work_tree(work_tree);
	}
	junk_git_dir = git_dir;
	atexit(remove_junk);
567
	sigchain_push_common(remove_junk_on_signal);
D
Daniel Barkalow 已提交
568

569
	setenv(CONFIG_ENVIRONMENT, mkpath("%s/config", git_dir), 1);
D
Daniel Barkalow 已提交
570

571
	if (safe_create_leading_directories_const(git_dir) < 0)
572
		die(_("could not create leading directories of '%s'"), git_dir);
573 574 575 576

	set_git_dir_init(git_dir, real_git_dir, 0);
	if (real_git_dir)
		git_dir = real_git_dir;
D
Daniel Barkalow 已提交
577

578 579
	if (0 <= option_verbosity) {
		if (option_bare)
580
			printf(_("Cloning into bare repository '%s'...\n"), dir);
581
		else
582
			printf(_("Cloning into '%s'...\n"), dir);
583
	}
584
	init_db(option_template, INIT_DB_QUIET);
585
	write_config(&option_config);
D
Daniel Barkalow 已提交
586

587 588 589 590 591 592 593
	/*
	 * 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);

J
Junio C Hamano 已提交
594
	git_config(git_default_config, NULL);
D
Daniel Barkalow 已提交
595 596

	if (option_bare) {
597 598
		if (option_mirror)
			src_ref_prefix = "refs/";
599
		strbuf_addstr(&branch_top, src_ref_prefix);
D
Daniel Barkalow 已提交
600 601 602

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

606 607
	strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);

608
	if (option_mirror || !option_bare) {
D
Daniel Barkalow 已提交
609
		/* Configure the remote */
610 611 612 613
		strbuf_addf(&key, "remote.%s.fetch", option_origin);
		git_config_set_multivar(key.buf, value.buf, "^$", 0);
		strbuf_reset(&key);

614
		if (option_mirror) {
615 616 617
			strbuf_addf(&key, "remote.%s.mirror", option_origin);
			git_config_set(key.buf, "true");
			strbuf_reset(&key);
618
		}
D
Daniel Barkalow 已提交
619 620
	}

621 622 623 624
	strbuf_addf(&key, "remote.%s.url", option_origin);
	git_config_set(key.buf, repo);
	strbuf_reset(&key);

625 626
	if (option_reference.nr)
		setup_reference();
627

628 629 630 631
	fetch_pattern = value.buf;
	refspec = parse_fetch_refspec(1, &fetch_pattern);

	strbuf_reset(&value);
D
Daniel Barkalow 已提交
632

633
	if (is_local) {
D
Daniel Barkalow 已提交
634
		refs = clone_local(path, git_dir);
635 636
		mapped_refs = wanted_peer_refs(refs, refspec);
	} else {
637
		struct remote *remote = remote_get(option_origin);
638
		transport = transport_get(remote, remote->url[0]);
D
Daniel Barkalow 已提交
639

640
		if (!transport->get_refs_list || !transport->fetch)
641
			die(_("Don't know how to clone %s"), transport->url);
642

D
Daniel Barkalow 已提交
643 644 645 646 647 648
		transport_set_option(transport, TRANS_OPT_KEEP, "yes");

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

649
		transport_set_verbosity(transport, option_verbosity, option_progress);
D
Daniel Barkalow 已提交
650

651 652 653 654
		if (option_upload_pack)
			transport_set_option(transport, TRANS_OPT_UPLOADPACK,
					     option_upload_pack);

D
Daniel Barkalow 已提交
655
		refs = transport_get_remote_refs(transport);
656 657 658 659
		if (refs) {
			mapped_refs = wanted_peer_refs(refs, refspec);
			transport_fetch_refs(transport, mapped_refs);
		}
D
Daniel Barkalow 已提交
660 661
	}

662 663
	if (refs) {
		clear_extra_refs();
D
Daniel Barkalow 已提交
664

665
		write_remote_refs(mapped_refs);
D
Daniel Barkalow 已提交
666

667
		remote_head = find_ref_by_name(refs, "HEAD");
668 669 670 671 672 673 674 675 676 677 678 679
		remote_head_points_at =
			guess_remote_head(remote_head, mapped_refs, 0);

		if (option_branch) {
			struct strbuf head = STRBUF_INIT;
			strbuf_addstr(&head, src_ref_prefix);
			strbuf_addstr(&head, option_branch);
			our_head_points_at =
				find_ref_by_name(mapped_refs, head.buf);
			strbuf_release(&head);

			if (!our_head_points_at) {
680 681
				warning(_("Remote branch %s not found in "
					"upstream %s, using HEAD instead"),
682 683 684 685 686 687
					option_branch, option_origin);
				our_head_points_at = remote_head_points_at;
			}
		}
		else
			our_head_points_at = remote_head_points_at;
688 689
	}
	else {
690
		warning(_("You appear to have cloned an empty repository."));
691 692
		our_head_points_at = NULL;
		remote_head_points_at = NULL;
693 694
		remote_head = NULL;
		option_no_checkout = 1;
695
		if (!option_bare)
696
			install_branch_config(0, "master", option_origin,
697
					      "refs/heads/master");
698
	}
D
Daniel Barkalow 已提交
699

700 701 702 703 704 705 706 707
	if (remote_head_points_at && !option_bare) {
		struct strbuf head_ref = STRBUF_INIT;
		strbuf_addstr(&head_ref, branch_top.buf);
		strbuf_addstr(&head_ref, "HEAD");
		create_symref(head_ref.buf,
			      remote_head_points_at->peer_ref->name,
			      reflog_msg.buf);
	}
D
Daniel Barkalow 已提交
708

709 710 711
	if (our_head_points_at) {
		/* Local default branch link */
		create_symref("HEAD", our_head_points_at->name, NULL);
D
Daniel Barkalow 已提交
712
		if (!option_bare) {
713 714
			const char *head = skip_prefix(our_head_points_at->name,
						       "refs/heads/");
D
Daniel Barkalow 已提交
715
			update_ref(reflog_msg.buf, "HEAD",
716
				   our_head_points_at->old_sha1,
D
Daniel Barkalow 已提交
717
				   NULL, 0, DIE_ON_ERR);
718
			install_branch_config(0, head, option_origin,
719
					      our_head_points_at->name);
D
Daniel Barkalow 已提交
720 721 722
		}
	} else if (remote_head) {
		/* Source had detached HEAD pointing somewhere. */
723
		if (!option_bare) {
D
Daniel Barkalow 已提交
724 725 726
			update_ref(reflog_msg.buf, "HEAD",
				   remote_head->old_sha1,
				   NULL, REF_NODEREF, DIE_ON_ERR);
727 728
			our_head_points_at = remote_head;
		}
D
Daniel Barkalow 已提交
729 730 731
	} else {
		/* Nothing to checkout out */
		if (!option_no_checkout)
732 733
			warning(_("remote HEAD refers to nonexistent ref, "
				"unable to checkout.\n"));
D
Daniel Barkalow 已提交
734 735 736
		option_no_checkout = 1;
	}

737
	if (transport) {
738
		transport_unlock_pack(transport);
739 740
		transport_disconnect(transport);
	}
741

D
Daniel Barkalow 已提交
742 743 744 745 746 747 748 749 750 751 752 753 754 755
	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;
756 757
		opts.merge = 1;
		opts.fn = oneway_merge;
758
		opts.verbose_update = (option_verbosity > 0);
759
		opts.src_index = &the_index;
D
Daniel Barkalow 已提交
760 761
		opts.dst_index = &the_index;

762
		tree = parse_tree_indirect(our_head_points_at->old_sha1);
D
Daniel Barkalow 已提交
763 764 765 766 767 768
		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))
769
			die(_("unable to write new index file"));
770 771

		err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1),
772 773
				sha1_to_hex(our_head_points_at->old_sha1), "1",
				NULL);
774 775 776

		if (!err && option_recursive)
			err = run_command_v_opt(argv_submodule, RUN_GIT_CMD);
D
Daniel Barkalow 已提交
777 778 779
	}

	strbuf_release(&reflog_msg);
780 781 782
	strbuf_release(&branch_top);
	strbuf_release(&key);
	strbuf_release(&value);
D
Daniel Barkalow 已提交
783
	junk_pid = 0;
784
	return err;
D
Daniel Barkalow 已提交
785
}