submodule.c 31.8 KB
Newer Older
1 2 3 4 5 6
#include "cache.h"
#include "submodule.h"
#include "dir.h"
#include "diff.h"
#include "commit.h"
#include "revision.h"
7
#include "run-command.h"
8
#include "diffcore.h"
9
#include "refs.h"
10
#include "string-list.h"
11
#include "sha1-array.h"
12
#include "argv-array.h"
13
#include "blob.h"
14

Stephen Boyd's avatar
Stephen Boyd committed
15 16 17
static struct string_list config_name_for_path;
static struct string_list config_fetch_recurse_submodules_for_name;
static struct string_list config_ignore_for_name;
18
static int config_fetch_recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND;
19
static struct string_list changed_submodule_paths;
20 21 22 23
static int initialized_fetch_ref_tips;
static struct sha1_array ref_tips_before_fetch;
static struct sha1_array ref_tips_after_fetch;

24 25 26 27 28 29 30 31 32
/*
 * The following flag is set if the .gitmodules file is unmerged. We then
 * disable recursion for all submodules where .git/config doesn't have a
 * matching config entry because we can't guess what might be configured in
 * .gitmodules unless the user resolves the conflict. When a command line
 * option is given (which always overrides configuration) this flag will be
 * ignored.
 */
static int gitmodules_is_unmerged;
33

34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
/*
 * This flag is set if the .gitmodules file had unstaged modifications on
 * startup. This must be checked before allowing modifications to the
 * .gitmodules file with the intention to stage them later, because when
 * continuing we would stage the modifications the user didn't stage herself
 * too. That might change in a future version when we learn to stage the
 * changes we do ourselves without staging any previous modifications.
 */
static int gitmodules_is_modified;


int is_staging_gitmodules_ok(void)
{
	return !gitmodules_is_modified;
}

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
/*
 * Try to update the "path" entry in the "submodule.<name>" section of the
 * .gitmodules file. Return 0 only if a .gitmodules file was found, a section
 * with the correct path=<oldpath> setting was found and we could update it.
 */
int update_path_in_gitmodules(const char *oldpath, const char *newpath)
{
	struct strbuf entry = STRBUF_INIT;
	struct string_list_item *path_option;

	if (!file_exists(".gitmodules")) /* Do nothing without .gitmodules */
		return -1;

	if (gitmodules_is_unmerged)
		die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));

	path_option = unsorted_string_list_lookup(&config_name_for_path, oldpath);
	if (!path_option) {
		warning(_("Could not find section in .gitmodules where path=%s"), oldpath);
		return -1;
	}
	strbuf_addstr(&entry, "submodule.");
	strbuf_addstr(&entry, path_option->util);
	strbuf_addstr(&entry, ".path");
	if (git_config_set_in_file(".gitmodules", entry.buf, newpath) < 0) {
		/* Maybe the user already did that, don't error out here */
		warning(_("Could not update .gitmodules entry %s"), entry.buf);
		strbuf_release(&entry);
		return -1;
	}
	strbuf_release(&entry);
	return 0;
}

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 109 110 111 112 113 114 115 116
/*
 * Try to remove the "submodule.<name>" section from .gitmodules where the given
 * path is configured. Return 0 only if a .gitmodules file was found, a section
 * with the correct path=<path> setting was found and we could remove it.
 */
int remove_path_from_gitmodules(const char *path)
{
	struct strbuf sect = STRBUF_INIT;
	struct string_list_item *path_option;

	if (!file_exists(".gitmodules")) /* Do nothing without .gitmodules */
		return -1;

	if (gitmodules_is_unmerged)
		die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));

	path_option = unsorted_string_list_lookup(&config_name_for_path, path);
	if (!path_option) {
		warning(_("Could not find section in .gitmodules where path=%s"), path);
		return -1;
	}
	strbuf_addstr(&sect, "submodule.");
	strbuf_addstr(&sect, path_option->util);
	if (git_config_rename_section_in_file(".gitmodules", sect.buf, NULL) < 0) {
		/* Maybe the user already did that, don't error out here */
		warning(_("Could not remove .gitmodules entry for %s"), path);
		strbuf_release(&sect);
		return -1;
	}
	strbuf_release(&sect);
	return 0;
}

117 118
void stage_updated_gitmodules(void)
{
119
	if (add_file_to_cache(".gitmodules", 0))
120 121 122
		die(_("staging updated .gitmodules failed"));
}

123
static int add_submodule_odb(const char *path)
124 125 126
{
	struct strbuf objects_directory = STRBUF_INIT;
	struct alternate_object_database *alt_odb;
127
	int ret = 0;
128
	const char *git_dir;
129

130
	strbuf_addf(&objects_directory, "%s/.git", path);
131
	git_dir = read_gitfile(objects_directory.buf);
132 133 134 135 136
	if (git_dir) {
		strbuf_reset(&objects_directory);
		strbuf_addstr(&objects_directory, git_dir);
	}
	strbuf_addstr(&objects_directory, "/objects/");
137 138 139 140
	if (!is_directory(objects_directory.buf)) {
		ret = -1;
		goto done;
	}
141 142 143 144 145
	/* avoid adding it twice */
	for (alt_odb = alt_odb_list; alt_odb; alt_odb = alt_odb->next)
		if (alt_odb->name - alt_odb->base == objects_directory.len &&
				!strncmp(alt_odb->base, objects_directory.buf,
					objects_directory.len))
146
			goto done;
147 148 149 150 151 152 153 154 155

	alt_odb = xmalloc(objects_directory.len + 42 + sizeof(*alt_odb));
	alt_odb->next = alt_odb_list;
	strcpy(alt_odb->base, objects_directory.buf);
	alt_odb->name = alt_odb->base + objects_directory.len;
	alt_odb->name[2] = '/';
	alt_odb->name[40] = '\0';
	alt_odb->name[41] = '\0';
	alt_odb_list = alt_odb;
156 157 158

	/* add possible alternates from the submodule */
	read_info_alternates(objects_directory.buf, 0);
159
	prepare_alt_odb();
160 161 162
done:
	strbuf_release(&objects_directory);
	return ret;
163 164
}

165 166 167 168 169 170 171 172 173
void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
					     const char *path)
{
	struct string_list_item *path_option, *ignore_option;
	path_option = unsorted_string_list_lookup(&config_name_for_path, path);
	if (path_option) {
		ignore_option = unsorted_string_list_lookup(&config_ignore_for_name, path_option->util);
		if (ignore_option)
			handle_ignore_submodules_arg(diffopt, ignore_option->util);
174 175
		else if (gitmodules_is_unmerged)
			DIFF_OPT_SET(diffopt, IGNORE_SUBMODULES);
176 177 178
	}
}

179
int submodule_config(const char *var, const char *value, void *cb)
180
{
181
	if (starts_with(var, "submodule."))
182
		return parse_submodule_config_option(var, value);
183
	else if (!strcmp(var, "fetch.recursesubmodules")) {
184
		config_fetch_recurse_submodules = parse_fetch_recurse_submodules_arg(var, value);
185 186
		return 0;
	}
187 188 189 190 191 192 193 194
	return 0;
}

void gitmodules_config(void)
{
	const char *work_tree = get_git_work_tree();
	if (work_tree) {
		struct strbuf gitmodules_path = STRBUF_INIT;
195
		int pos;
196 197
		strbuf_addstr(&gitmodules_path, work_tree);
		strbuf_addstr(&gitmodules_path, "/.gitmodules");
198 199 200 201 202 203 204 205 206 207 208
		if (read_cache() < 0)
			die("index file corrupt");
		pos = cache_name_pos(".gitmodules", 11);
		if (pos < 0) { /* .gitmodules not found or isn't merged */
			pos = -1 - pos;
			if (active_nr > pos) {  /* there is a .gitmodules */
				const struct cache_entry *ce = active_cache[pos];
				if (ce_namelen(ce) == 11 &&
				    !memcmp(ce->name, ".gitmodules", 11))
					gitmodules_is_unmerged = 1;
			}
209 210 211 212 213
		} else if (pos < active_nr) {
			struct stat st;
			if (lstat(".gitmodules", &st) == 0 &&
			    ce_match_stat(active_cache[pos], &st, 0) & DATA_CHANGED)
				gitmodules_is_modified = 1;
214 215 216 217
		}

		if (!gitmodules_is_unmerged)
			git_config_from_file(submodule_config, gitmodules_path.buf, NULL);
218 219 220 221
		strbuf_release(&gitmodules_path);
	}
}

222 223 224
int parse_submodule_config_option(const char *var, const char *value)
{
	struct string_list_item *config;
225 226
	const char *name, *key;
	int namelen;
227

228 229
	if (parse_config_key(var, "submodule", &name, &namelen, &key) < 0 || !name)
		return 0;
230

231
	if (!strcmp(key, "path")) {
232 233 234
		if (!value)
			return config_error_nonbool(var);

235 236 237 238 239
		config = unsorted_string_list_lookup(&config_name_for_path, value);
		if (config)
			free(config->util);
		else
			config = string_list_append(&config_name_for_path, xstrdup(value));
240
		config->util = xmemdupz(name, namelen);
241
	} else if (!strcmp(key, "fetchrecursesubmodules")) {
242 243
		char *name_cstr = xmemdupz(name, namelen);
		config = unsorted_string_list_lookup(&config_fetch_recurse_submodules_for_name, name_cstr);
244
		if (!config)
245 246 247
			config = string_list_append(&config_fetch_recurse_submodules_for_name, name_cstr);
		else
			free(name_cstr);
248
		config->util = (void *)(intptr_t)parse_fetch_recurse_submodules_arg(var, value);
249
	} else if (!strcmp(key, "ignore")) {
250 251
		char *name_cstr;

252 253 254
		if (!value)
			return config_error_nonbool(var);

255 256 257 258 259 260
		if (strcmp(value, "untracked") && strcmp(value, "dirty") &&
		    strcmp(value, "all") && strcmp(value, "none")) {
			warning("Invalid parameter \"%s\" for config option \"submodule.%s.ignore\"", value, var);
			return 0;
		}

261 262 263
		name_cstr = xmemdupz(name, namelen);
		config = unsorted_string_list_lookup(&config_ignore_for_name, name_cstr);
		if (config) {
264
			free(config->util);
265 266 267
			free(name_cstr);
		} else
			config = string_list_append(&config_ignore_for_name, name_cstr);
268 269 270 271 272 273
		config->util = xstrdup(value);
		return 0;
	}
	return 0;
}

274 275 276
void handle_ignore_submodules_arg(struct diff_options *diffopt,
				  const char *arg)
{
277 278 279 280
	DIFF_OPT_CLR(diffopt, IGNORE_SUBMODULES);
	DIFF_OPT_CLR(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES);
	DIFF_OPT_CLR(diffopt, IGNORE_DIRTY_SUBMODULES);

281 282 283 284 285 286
	if (!strcmp(arg, "all"))
		DIFF_OPT_SET(diffopt, IGNORE_SUBMODULES);
	else if (!strcmp(arg, "untracked"))
		DIFF_OPT_SET(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES);
	else if (!strcmp(arg, "dirty"))
		DIFF_OPT_SET(diffopt, IGNORE_DIRTY_SUBMODULES);
287
	else if (strcmp(arg, "none"))
288 289 290
		die("bad --ignore-submodules argument: %s", arg);
}

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
static int prepare_submodule_summary(struct rev_info *rev, const char *path,
		struct commit *left, struct commit *right,
		int *fast_forward, int *fast_backward)
{
	struct commit_list *merge_bases, *list;

	init_revisions(rev, NULL);
	setup_revisions(0, NULL, rev, NULL);
	rev->left_right = 1;
	rev->first_parent_only = 1;
	left->object.flags |= SYMMETRIC_LEFT;
	add_pending_object(rev, &left->object, path);
	add_pending_object(rev, &right->object, path);
	merge_bases = get_merge_bases(left, right, 1);
	if (merge_bases) {
		if (merge_bases->item == left)
			*fast_forward = 1;
		else if (merge_bases->item == right)
			*fast_backward = 1;
	}
	for (list = merge_bases; list; list = list->next) {
		list->item->object.flags |= UNINTERESTING;
		add_pending_object(rev, &list->item->object,
			sha1_to_hex(list->item->object.sha1));
	}
	return prepare_revision_walk(rev);
}

static void print_submodule_summary(struct rev_info *rev, FILE *f,
320
		const char *line_prefix,
321 322 323 324 325 326 327 328 329
		const char *del, const char *add, const char *reset)
{
	static const char format[] = "  %m %s";
	struct strbuf sb = STRBUF_INIT;
	struct commit *commit;

	while ((commit = get_revision(rev))) {
		struct pretty_print_context ctx = {0};
		ctx.date_mode = rev->date_mode;
330
		ctx.output_encoding = get_log_output_encoding();
331
		strbuf_setlen(&sb, 0);
332
		strbuf_addstr(&sb, line_prefix);
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
		if (commit->object.flags & SYMMETRIC_LEFT) {
			if (del)
				strbuf_addstr(&sb, del);
		}
		else if (add)
			strbuf_addstr(&sb, add);
		format_commit_message(commit, format, &sb, &ctx);
		if (reset)
			strbuf_addstr(&sb, reset);
		strbuf_addch(&sb, '\n');
		fprintf(f, "%s", sb.buf);
	}
	strbuf_release(&sb);
}

348 349 350 351 352 353 354 355 356 357 358 359 360 361
int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg)
{
	switch (git_config_maybe_bool(opt, arg)) {
	case 1:
		return RECURSE_SUBMODULES_ON;
	case 0:
		return RECURSE_SUBMODULES_OFF;
	default:
		if (!strcmp(arg, "on-demand"))
			return RECURSE_SUBMODULES_ON_DEMAND;
		die("bad %s argument: %s", opt, arg);
	}
}

362
void show_submodule_summary(FILE *f, const char *path,
363
		const char *line_prefix,
364
		unsigned char one[20], unsigned char two[20],
365
		unsigned dirty_submodule, const char *meta,
366 367 368
		const char *del, const char *add, const char *reset)
{
	struct rev_info rev;
369
	struct commit *left = NULL, *right = NULL;
370 371 372 373 374 375 376 377 378 379 380 381 382
	const char *message = NULL;
	struct strbuf sb = STRBUF_INIT;
	int fast_forward = 0, fast_backward = 0;

	if (is_null_sha1(two))
		message = "(submodule deleted)";
	else if (add_submodule_odb(path))
		message = "(not checked out)";
	else if (is_null_sha1(one))
		message = "(new submodule)";
	else if (!(left = lookup_commit_reference(one)) ||
		 !(right = lookup_commit_reference(two)))
		message = "(commits not present)";
383 384
	else if (prepare_submodule_summary(&rev, path, left, right,
					   &fast_forward, &fast_backward))
385
		message = "(revision walker failed)";
386

387
	if (dirty_submodule & DIRTY_SUBMODULE_UNTRACKED)
388 389
		fprintf(f, "%sSubmodule %s contains untracked content\n",
			line_prefix, path);
390
	if (dirty_submodule & DIRTY_SUBMODULE_MODIFIED)
391 392
		fprintf(f, "%sSubmodule %s contains modified content\n",
			line_prefix, path);
393 394 395 396 397 398

	if (!hashcmp(one, two)) {
		strbuf_release(&sb);
		return;
	}

399
	strbuf_addf(&sb, "%s%sSubmodule %s %s..", line_prefix, meta, path,
400 401 402 403 404
			find_unique_abbrev(one, DEFAULT_ABBREV));
	if (!fast_backward && !fast_forward)
		strbuf_addch(&sb, '.');
	strbuf_addf(&sb, "%s", find_unique_abbrev(two, DEFAULT_ABBREV));
	if (message)
405
		strbuf_addf(&sb, " %s%s\n", message, reset);
406
	else
407
		strbuf_addf(&sb, "%s:%s\n", fast_backward ? " (rewind)" : "", reset);
408 409
	fwrite(sb.buf, sb.len, 1, f);

410
	if (!message) /* only NULL if we succeeded in setting up the walk */
411
		print_submodule_summary(&rev, f, line_prefix, del, add, reset);
412
	if (left)
413
		clear_commit_marks(left, ~0);
414
	if (right)
415
		clear_commit_marks(right, ~0);
416

417 418
	strbuf_release(&sb);
}
419

420 421 422 423 424
void set_config_fetch_recurse_submodules(int value)
{
	config_fetch_recurse_submodules = value;
}

425 426 427 428 429 430 431 432 433 434 435
static int has_remote(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
{
	return 1;
}

static int submodule_needs_pushing(const char *path, const unsigned char sha1[20])
{
	if (add_submodule_odb(path) || !lookup_commit_reference(sha1))
		return 0;

	if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
436
		struct child_process cp = CHILD_PROCESS_INIT;
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
		const char *argv[] = {"rev-list", NULL, "--not", "--remotes", "-n", "1" , NULL};
		struct strbuf buf = STRBUF_INIT;
		int needs_pushing = 0;

		argv[1] = sha1_to_hex(sha1);
		cp.argv = argv;
		cp.env = local_repo_env;
		cp.git_cmd = 1;
		cp.no_stdin = 1;
		cp.out = -1;
		cp.dir = path;
		if (start_command(&cp))
			die("Could not run 'git rev-list %s --not --remotes -n 1' command in submodule %s",
				sha1_to_hex(sha1), path);
		if (strbuf_read(&buf, cp.out, 41))
			needs_pushing = 1;
		finish_command(&cp);
		close(cp.out);
		strbuf_release(&buf);
		return needs_pushing;
	}

	return 0;
}

static void collect_submodules_from_diff(struct diff_queue_struct *q,
					 struct diff_options *options,
					 void *data)
{
	int i;
467
	struct string_list *needs_pushing = data;
468 469 470 471 472

	for (i = 0; i < q->nr; i++) {
		struct diff_filepair *p = q->queue[i];
		if (!S_ISGITLINK(p->two->mode))
			continue;
473 474
		if (submodule_needs_pushing(p->two->path, p->two->sha1))
			string_list_insert(needs_pushing, p->two->path);
475 476 477
	}
}

478 479
static void find_unpushed_submodule_commits(struct commit *commit,
		struct string_list *needs_pushing)
480 481 482 483 484 485 486
{
	struct rev_info rev;

	init_revisions(&rev, NULL);
	rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
	rev.diffopt.format_callback = collect_submodules_from_diff;
	rev.diffopt.format_callback_data = needs_pushing;
487
	diff_tree_combined_merge(commit, 1, &rev);
488 489
}

490 491
int find_unpushed_submodules(unsigned char new_sha1[20],
		const char *remotes_name, struct string_list *needs_pushing)
492 493 494 495 496 497
{
	struct rev_info rev;
	struct commit *commit;
	const char *argv[] = {NULL, NULL, "--not", "NULL", NULL};
	int argc = ARRAY_SIZE(argv) - 1;
	char *sha1_copy;
498

499 500 501 502 503 504 505 506 507 508 509
	struct strbuf remotes_arg = STRBUF_INIT;

	strbuf_addf(&remotes_arg, "--remotes=%s", remotes_name);
	init_revisions(&rev, NULL);
	sha1_copy = xstrdup(sha1_to_hex(new_sha1));
	argv[1] = sha1_copy;
	argv[3] = remotes_arg.buf;
	setup_revisions(argc, argv, &rev, NULL);
	if (prepare_revision_walk(&rev))
		die("revision walk setup failed");

510 511
	while ((commit = get_revision(&rev)) != NULL)
		find_unpushed_submodule_commits(commit, needs_pushing);
512

513
	reset_revision_walk();
514 515 516
	free(sha1_copy);
	strbuf_release(&remotes_arg);

517
	return needs_pushing->nr;
518 519
}

520 521 522 523 524 525
static int push_submodule(const char *path)
{
	if (add_submodule_odb(path))
		return 1;

	if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
526
		struct child_process cp = CHILD_PROCESS_INIT;
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
		const char *argv[] = {"push", NULL};

		cp.argv = argv;
		cp.env = local_repo_env;
		cp.git_cmd = 1;
		cp.no_stdin = 1;
		cp.dir = path;
		if (run_command(&cp))
			return 0;
		close(cp.out);
	}

	return 1;
}

int push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name)
{
	int i, ret = 1;
545
	struct string_list needs_pushing = STRING_LIST_INIT_DUP;
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563

	if (!find_unpushed_submodules(new_sha1, remotes_name, &needs_pushing))
		return 1;

	for (i = 0; i < needs_pushing.nr; i++) {
		const char *path = needs_pushing.items[i].string;
		fprintf(stderr, "Pushing submodule '%s'\n", path);
		if (!push_submodule(path)) {
			fprintf(stderr, "Unable to push submodule '%s'\n", path);
			ret = 0;
		}
	}

	string_list_clear(&needs_pushing, 0);

	return ret;
}

564 565 566 567 568 569
static int is_submodule_commit_present(const char *path, unsigned char sha1[20])
{
	int is_present = 0;
	if (!add_submodule_odb(path) && lookup_commit_reference(sha1)) {
		/* Even if the submodule is checked out and the commit is
		 * present, make sure it is reachable from a ref. */
570
		struct child_process cp = CHILD_PROCESS_INIT;
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589
		const char *argv[] = {"rev-list", "-n", "1", NULL, "--not", "--all", NULL};
		struct strbuf buf = STRBUF_INIT;

		argv[3] = sha1_to_hex(sha1);
		cp.argv = argv;
		cp.env = local_repo_env;
		cp.git_cmd = 1;
		cp.no_stdin = 1;
		cp.out = -1;
		cp.dir = path;
		if (!run_command(&cp) && !strbuf_read(&buf, cp.out, 1024))
			is_present = 1;

		close(cp.out);
		strbuf_release(&buf);
	}
	return is_present;
}

590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
static void submodule_collect_changed_cb(struct diff_queue_struct *q,
					 struct diff_options *options,
					 void *data)
{
	int i;
	for (i = 0; i < q->nr; i++) {
		struct diff_filepair *p = q->queue[i];
		if (!S_ISGITLINK(p->two->mode))
			continue;

		if (S_ISGITLINK(p->one->mode)) {
			/* NEEDSWORK: We should honor the name configured in
			 * the .gitmodules file of the commit we are examining
			 * here to be able to correctly follow submodules
			 * being moved around. */
			struct string_list_item *path;
			path = unsorted_string_list_lookup(&changed_submodule_paths, p->two->path);
607
			if (!path && !is_submodule_commit_present(p->two->path, p->two->sha1))
608 609 610 611 612 613 614 615 616 617 618 619 620
				string_list_append(&changed_submodule_paths, xstrdup(p->two->path));
		} else {
			/* Submodule is new or was moved here */
			/* NEEDSWORK: When the .git directories of submodules
			 * live inside the superprojects .git directory some
			 * day we should fetch new submodules directly into
			 * that location too when config or options request
			 * that so they can be checked out from there. */
			continue;
		}
	}
}

621 622 623 624 625 626 627
static int add_sha1_to_array(const char *ref, const unsigned char *sha1,
			     int flags, void *data)
{
	sha1_array_append(data, sha1);
	return 0;
}

628
void check_for_new_submodule_commits(unsigned char new_sha1[20])
629 630 631 632 633 634 635 636 637 638 639
{
	if (!initialized_fetch_ref_tips) {
		for_each_ref(add_sha1_to_array, &ref_tips_before_fetch);
		initialized_fetch_ref_tips = 1;
	}

	sha1_array_append(&ref_tips_after_fetch, new_sha1);
}

static void add_sha1_to_argv(const unsigned char sha1[20], void *data)
{
640
	argv_array_push(data, sha1_to_hex(sha1));
641 642 643
}

static void calculate_changed_submodule_paths(void)
644 645 646
{
	struct rev_info rev;
	struct commit *commit;
647
	struct argv_array argv = ARGV_ARRAY_INIT;
648

649 650 651 652
	/* No need to check if there are no submodules configured */
	if (!config_name_for_path.nr)
		return;

653
	init_revisions(&rev, NULL);
654
	argv_array_push(&argv, "--"); /* argv[0] program name */
655 656
	sha1_array_for_each_unique(&ref_tips_after_fetch,
				   add_sha1_to_argv, &argv);
657
	argv_array_push(&argv, "--not");
658 659 660
	sha1_array_for_each_unique(&ref_tips_before_fetch,
				   add_sha1_to_argv, &argv);
	setup_revisions(argv.argc, argv.argv, &rev, NULL);
661 662 663 664 665 666 667 668 669 670 671 672
	if (prepare_revision_walk(&rev))
		die("revision walk setup failed");

	/*
	 * Collect all submodules (whether checked out or not) for which new
	 * commits have been recorded upstream in "changed_submodule_paths".
	 */
	while ((commit = get_revision(&rev))) {
		struct commit_list *parent = commit->parents;
		while (parent) {
			struct diff_options diff_opts;
			diff_setup(&diff_opts);
673
			DIFF_OPT_SET(&diff_opts, RECURSIVE);
674 675
			diff_opts.output_format |= DIFF_FORMAT_CALLBACK;
			diff_opts.format_callback = submodule_collect_changed_cb;
Thomas Rast's avatar
Thomas Rast committed
676
			diff_setup_done(&diff_opts);
677 678 679 680 681 682
			diff_tree_sha1(parent->item->object.sha1, commit->object.sha1, "", &diff_opts);
			diffcore_std(&diff_opts);
			diff_flush(&diff_opts);
			parent = parent->next;
		}
	}
683

684
	argv_array_clear(&argv);
685 686 687
	sha1_array_clear(&ref_tips_before_fetch);
	sha1_array_clear(&ref_tips_after_fetch);
	initialized_fetch_ref_tips = 0;
688 689
}

690
int fetch_populated_submodules(const struct argv_array *options,
691
			       const char *prefix, int command_line_option,
692
			       int quiet)
693
{
694
	int i, result = 0;
695
	struct child_process cp = CHILD_PROCESS_INIT;
696
	struct argv_array argv = ARGV_ARRAY_INIT;
697 698 699
	struct string_list_item *name_for_path;
	const char *work_tree = get_git_work_tree();
	if (!work_tree)
700
		goto out;
701

702 703
	if (read_cache() < 0)
		die("index file corrupt");
704

705 706 707 708 709
	argv_array_push(&argv, "fetch");
	for (i = 0; i < options->argc; i++)
		argv_array_push(&argv, options->argv[i]);
	argv_array_push(&argv, "--recurse-submodules-default");
	/* default value, "--submodule-prefix" and its value are added later */
710 711 712 713 714

	cp.env = local_repo_env;
	cp.git_cmd = 1;
	cp.no_stdin = 1;

715 716
	calculate_changed_submodule_paths();

717 718 719 720
	for (i = 0; i < active_nr; i++) {
		struct strbuf submodule_path = STRBUF_INIT;
		struct strbuf submodule_git_dir = STRBUF_INIT;
		struct strbuf submodule_prefix = STRBUF_INIT;
721
		const struct cache_entry *ce = active_cache[i];
722
		const char *git_dir, *name, *default_argv;
723 724 725 726 727 728 729 730 731

		if (!S_ISGITLINK(ce->ce_mode))
			continue;

		name = ce->name;
		name_for_path = unsorted_string_list_lookup(&config_name_for_path, ce->name);
		if (name_for_path)
			name = name_for_path->util;

732
		default_argv = "yes";
733
		if (command_line_option == RECURSE_SUBMODULES_DEFAULT) {
734 735 736
			struct string_list_item *fetch_recurse_submodules_option;
			fetch_recurse_submodules_option = unsorted_string_list_lookup(&config_fetch_recurse_submodules_for_name, name);
			if (fetch_recurse_submodules_option) {
737
				if ((intptr_t)fetch_recurse_submodules_option->util == RECURSE_SUBMODULES_OFF)
738
					continue;
739 740 741 742 743
				if ((intptr_t)fetch_recurse_submodules_option->util == RECURSE_SUBMODULES_ON_DEMAND) {
					if (!unsorted_string_list_lookup(&changed_submodule_paths, ce->name))
						continue;
					default_argv = "on-demand";
				}
744
			} else {
745 746
				if ((config_fetch_recurse_submodules == RECURSE_SUBMODULES_OFF) ||
				    gitmodules_is_unmerged)
747
					continue;
748 749 750 751 752
				if (config_fetch_recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) {
					if (!unsorted_string_list_lookup(&changed_submodule_paths, ce->name))
						continue;
					default_argv = "on-demand";
				}
753
			}
754 755 756 757
		} else if (command_line_option == RECURSE_SUBMODULES_ON_DEMAND) {
			if (!unsorted_string_list_lookup(&changed_submodule_paths, ce->name))
				continue;
			default_argv = "on-demand";
758 759
		}

760 761 762
		strbuf_addf(&submodule_path, "%s/%s", work_tree, ce->name);
		strbuf_addf(&submodule_git_dir, "%s/.git", submodule_path.buf);
		strbuf_addf(&submodule_prefix, "%s%s/", prefix, ce->name);
763
		git_dir = read_gitfile(submodule_git_dir.buf);
764 765 766 767 768 769
		if (!git_dir)
			git_dir = submodule_git_dir.buf;
		if (is_directory(git_dir)) {
			if (!quiet)
				printf("Fetching submodule %s%s\n", prefix, ce->name);
			cp.dir = submodule_path.buf;
770 771 772 773
			argv_array_push(&argv, default_argv);
			argv_array_push(&argv, "--submodule-prefix");
			argv_array_push(&argv, submodule_prefix.buf);
			cp.argv = argv.argv;
774 775
			if (run_command(&cp))
				result = 1;
776 777 778
			argv_array_pop(&argv);
			argv_array_pop(&argv);
			argv_array_pop(&argv);
779 780 781 782 783
		}
		strbuf_release(&submodule_path);
		strbuf_release(&submodule_git_dir);
		strbuf_release(&submodule_prefix);
	}
784
	argv_array_clear(&argv);
785 786
out:
	string_list_clear(&changed_submodule_paths, 1);
787 788 789
	return result;
}

790
unsigned is_submodule_modified(const char *path, int ignore_untracked)
791
{
792
	ssize_t len;
793
	struct child_process cp = CHILD_PROCESS_INIT;
794 795 796 797
	const char *argv[] = {
		"status",
		"--porcelain",
		NULL,
798
		NULL,
799 800
	};
	struct strbuf buf = STRBUF_INIT;
801 802
	unsigned dirty_submodule = 0;
	const char *line, *next_line;
803
	const char *git_dir;
804

805
	strbuf_addf(&buf, "%s/.git", path);
806
	git_dir = read_gitfile(buf.buf);
807 808 809
	if (!git_dir)
		git_dir = buf.buf;
	if (!is_directory(git_dir)) {
810 811 812 813 814 815 816
		strbuf_release(&buf);
		/* The submodule is not checked out, so it is not modified */
		return 0;

	}
	strbuf_reset(&buf);

817 818 819
	if (ignore_untracked)
		argv[2] = "-uno";

820
	cp.argv = argv;
821
	cp.env = local_repo_env;
822 823 824
	cp.git_cmd = 1;
	cp.no_stdin = 1;
	cp.out = -1;
825
	cp.dir = path;
826
	if (start_command(&cp))
827
		die("Could not run 'git status --porcelain' in submodule %s", path);
828 829

	len = strbuf_read(&buf, cp.out, 1024);
830 831 832 833 834 835 836 837
	line = buf.buf;
	while (len > 2) {
		if ((line[0] == '?') && (line[1] == '?')) {
			dirty_submodule |= DIRTY_SUBMODULE_UNTRACKED;
			if (dirty_submodule & DIRTY_SUBMODULE_MODIFIED)
				break;
		} else {
			dirty_submodule |= DIRTY_SUBMODULE_MODIFIED;
838 839
			if (ignore_untracked ||
			    (dirty_submodule & DIRTY_SUBMODULE_UNTRACKED))
840 841 842 843 844 845 846 847 848
				break;
		}
		next_line = strchr(line, '\n');
		if (!next_line)
			break;
		next_line++;
		len -= (next_line - line);
		line = next_line;
	}
849 850 851
	close(cp.out);

	if (finish_command(&cp))
852
		die("'git status --porcelain' failed in submodule %s", path);
853 854

	strbuf_release(&buf);
855
	return dirty_submodule;
856
}
857

858 859
int submodule_uses_gitfile(const char *path)
{
860
	struct child_process cp = CHILD_PROCESS_INIT;
861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897
	const char *argv[] = {
		"submodule",
		"foreach",
		"--quiet",
		"--recursive",
		"test -f .git",
		NULL,
	};
	struct strbuf buf = STRBUF_INIT;
	const char *git_dir;

	strbuf_addf(&buf, "%s/.git", path);
	git_dir = read_gitfile(buf.buf);
	if (!git_dir) {
		strbuf_release(&buf);
		return 0;
	}
	strbuf_release(&buf);

	/* Now test that all nested submodules use a gitfile too */
	cp.argv = argv;
	cp.env = local_repo_env;
	cp.git_cmd = 1;
	cp.no_stdin = 1;
	cp.no_stderr = 1;
	cp.no_stdout = 1;
	cp.dir = path;
	if (run_command(&cp))
		return 0;

	return 1;
}

int ok_to_remove_submodule(const char *path)
{
	struct stat st;
	ssize_t len;
898
	struct child_process cp = CHILD_PROCESS_INIT;
899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935
	const char *argv[] = {
		"status",
		"--porcelain",
		"-u",
		"--ignore-submodules=none",
		NULL,
	};
	struct strbuf buf = STRBUF_INIT;
	int ok_to_remove = 1;

	if ((lstat(path, &st) < 0) || is_empty_dir(path))
		return 1;

	if (!submodule_uses_gitfile(path))
		return 0;

	cp.argv = argv;
	cp.env = local_repo_env;
	cp.git_cmd = 1;
	cp.no_stdin = 1;
	cp.out = -1;
	cp.dir = path;
	if (start_command(&cp))
		die("Could not run 'git status --porcelain -uall --ignore-submodules=none' in submodule %s", path);

	len = strbuf_read(&buf, cp.out, 1024);
	if (len > 2)
		ok_to_remove = 0;
	close(cp.out);

	if (finish_command(&cp))
		die("'git status --porcelain -uall --ignore-submodules=none' failed in submodule %s", path);

	strbuf_release(&buf);
	return ok_to_remove;
}

936 937 938 939
static int find_first_merges(struct object_array *result, const char *path,
		struct commit *a, struct commit *b)
{
	int i, j;
940
	struct object_array merges = OBJECT_ARRAY_INIT;
941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957
	struct commit *commit;
	int contains_another;

	char merged_revision[42];
	const char *rev_args[] = { "rev-list", "--merges", "--ancestry-path",
				   "--all", merged_revision, NULL };
	struct rev_info revs;
	struct setup_revision_opt rev_opts;

	memset(result, 0, sizeof(struct object_array));
	memset(&rev_opts, 0, sizeof(rev_opts));

	/* get all revisions that merge commit a */
	snprintf(merged_revision, sizeof(merged_revision), "^%s",
			sha1_to_hex(a->object.sha1));
	init_revisions(&revs, NULL);
	rev_opts.submodule = path;
958
	setup_revisions(ARRAY_SIZE(rev_args)-1, rev_args, &revs, &rev_opts);
959 960 961 962 963 964

	/* save all revisions from the above list that contain b */
	if (prepare_revision_walk(&revs))
		die("revision walk setup failed");
	while ((commit = get_revision(&revs)) != NULL) {
		struct object *o = &(commit->object);
965
		if (in_merge_bases(b, commit))
966 967
			add_object_array(o, NULL, &merges);
	}
968
	reset_revision_walk();
969 970 971 972 973 974 975 976 977 978 979

	/* Now we've got all merges that contain a and b. Prune all
	 * merges that contain another found merge and save them in
	 * result.
	 */
	for (i = 0; i < merges.nr; i++) {
		struct commit *m1 = (struct commit *) merges.objects[i].item;

		contains_another = 0;
		for (j = 0; j < merges.nr; j++) {
			struct commit *m2 = (struct commit *) merges.objects[j].item;
980
			if (i != j && in_merge_bases(m2, m1)) {
981 982 983 984 985 986
				contains_another = 1;
				break;
			}
		}

		if (!contains_another)
987
			add_object_array(merges.objects[i].item, NULL, result);
988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
	}

	free(merges.objects);
	return result->nr;
}

static void print_commit(struct commit *commit)
{
	struct strbuf sb = STRBUF_INIT;
	struct pretty_print_context ctx = {0};
	ctx.date_mode = DATE_NORMAL;
	format_commit_message(commit, " %h: %m %s", &sb, &ctx);
	fprintf(stderr, "%s\n", sb.buf);
	strbuf_release(&sb);
}

#define MERGE_WARNING(path, msg) \
	warning("Failed to merge submodule %s (%s)", path, msg);

int merge_submodule(unsigned char result[20], const char *path,
		    const unsigned char base[20], const unsigned char a[20],
1009
		    const unsigned char b[20], int search)
1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
{
	struct commit *commit_base, *commit_a, *commit_b;
	int parent_count;
	struct object_array merges;

	int i;

	/* store a in result in case we fail */
	hashcpy(result, a);

	/* we can not handle deletion conflicts */
	if (is_null_sha1(base))
		return 0;
	if (is_null_sha1(a))
		return 0;
	if (is_null_sha1(b))
		return 0;

	if (add_submodule_odb(path)) {
		MERGE_WARNING(path, "not checked out");
		return 0;
	}

	if (!(commit_base = lookup_commit_reference(base)) ||
	    !(commit_a = lookup_commit_reference(a)) ||
	    !(commit_b = lookup_commit_reference(b))) {
		MERGE_WARNING(path, "commits not present");
		return 0;
	}

	/* check whether both changes are forward */
1041 1042
	if (!in_merge_bases(commit_base, commit_a) ||
	    !in_merge_bases(commit_base, commit_b)) {
1043 1044 1045 1046 1047
		MERGE_WARNING(path, "commits don't follow merge-base");
		return 0;
	}

	/* Case #1: a is contained in b or vice versa */
1048
	if (in_merge_bases(commit_a, commit_b)) {
1049 1050 1051
		hashcpy(result, b);
		return 1;
	}
1052
	if (in_merge_bases(commit_b, commit_a)) {
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063
		hashcpy(result, a);
		return 1;
	}

	/*
	 * Case #2: There are one or more merges that contain a and b in
	 * the submodule. If there is only one, then present it as a
	 * suggestion to the user, but leave it marked unmerged so the
	 * user needs to confirm the resolution.
	 */

1064 1065 1066 1067
	/* Skip the search if makes no sense to the calling context.  */
	if (!search)
		return 0;

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
	/* find commit which merges them */
	parent_count = find_first_merges(&merges, path, commit_a, commit_b);
	switch (parent_count) {
	case 0:
		MERGE_WARNING(path, "merge following commits not found");
		break;

	case 1:
		MERGE_WARNING(path, "not fast-forward");
		fprintf(stderr, "Found a possible merge resolution "
				"for the submodule:\n");
		print_commit((struct commit *) merges.objects[0].item);
		fprintf(stderr,
			"If this is correct simply add it to the index "
			"for example\n"
			"by using:\n\n"
			"  git update-index --cacheinfo 160000 %s \"%s\"\n\n"
			"which will accept this suggestion.\n",
			sha1_to_hex(merges.objects[0].item->sha1), path);
		break;

	default:
		MERGE_WARNING(path, "multiple merges found");
		for (i = 0; i < merges.nr; i++)
			print_commit((struct commit *) merges.objects[i].item);
	}

	free(merges.objects);
	return 0;
}
1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128

/* Update gitfile and core.worktree setting to connect work tree and git dir */
void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir)
{
	struct strbuf file_name = STRBUF_INIT;
	struct strbuf rel_path = STRBUF_INIT;
	const char *real_work_tree = xstrdup(real_path(work_tree));
	FILE *fp;

	/* Update gitfile */
	strbuf_addf(&file_name, "%s/.git", work_tree);
	fp = fopen(file_name.buf, "w");
	if (!fp)
		die(_("Could not create git link %s"), file_name.buf);
	fprintf(fp, "gitdir: %s\n", relative_path(git_dir, real_work_tree,
						  &rel_path));
	fclose(fp);

	/* Update core.worktree setting */
	strbuf_reset(&file_name);
	strbuf_addf(&file_name, "%s/config", git_dir);
	if (git_config_set_in_file(file_name.buf, "core.worktree",
				   relative_path(real_work_tree, git_dir,
						 &rel_path)))
		die(_("Could not set core.worktree in %s"),
		    file_name.buf);

	strbuf_release(&file_name);
	strbuf_release(&rel_path);
	free((void *)real_work_tree);
}