Пример #1
0
int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
{
	const unsigned char *bases[21];
	unsigned bases_count = 0;
	int i, failed;
	unsigned char h1[20], h2[20];
	struct merge_options o;
	struct commit *result;

	init_merge_options(&o);
	if (argv[0] && ends_with(argv[0], "-subtree"))
		o.subtree_shift = "";

	if (argc < 4)
		usagef(builtin_merge_recursive_usage, argv[0]);

	for (i = 1; i < argc; ++i) {
		const char *arg = argv[i];

		if (starts_with(arg, "--")) {
			if (!arg[2])
				break;
			if (parse_merge_opt(&o, arg + 2))
				die("Unknown option %s", arg);
			continue;
		}
		if (bases_count < ARRAY_SIZE(bases)-1) {
			unsigned char *sha = xmalloc(20);
			if (get_sha1(argv[i], sha))
				die("Could not parse object '%s'", argv[i]);
			bases[bases_count++] = sha;
		}
		else
			warning("Cannot handle more than %d bases. "
				"Ignoring %s.",
				(int)ARRAY_SIZE(bases)-1, argv[i]);
	}
	if (argc - i != 3) /* "--" "<head>" "<remote>" */
		die("Not handling anything other than two heads merge.");

	o.branch1 = argv[++i];
	o.branch2 = argv[++i];

	if (get_sha1(o.branch1, h1))
		die("Could not resolve ref '%s'", o.branch1);
	if (get_sha1(o.branch2, h2))
		die("Could not resolve ref '%s'", o.branch2);

	o.branch1 = better_branch_name(o.branch1);
	o.branch2 = better_branch_name(o.branch2);

	if (o.verbosity >= 3)
		printf("Merging %s with %s\n", o.branch1, o.branch2);

	failed = merge_recursive_generic(&o, h1, h2, bases_count, bases, &result);
	if (failed < 0)
		return 128; /* die() error code */
	return failed;
}
Пример #2
0
static struct commit *get_ref(const char *ref)
{
	unsigned char sha1[20];
	struct object *object;

	if (get_sha1(ref, sha1))
		die("Could not resolve ref '%s'", ref);
	object = deref_tag(parse_object(sha1), ref, strlen(ref));
	if (!object)
		return NULL;
	if (object->type == OBJ_TREE)
		return make_virtual_commit((struct tree*)object,
			better_branch_name(ref));
	if (object->type != OBJ_COMMIT)
		return NULL;
	if (parse_commit((struct commit *)object))
		die("Could not parse commit '%s'", sha1_to_hex(object->sha1));
	return (struct commit *)object;
}
Пример #3
0
int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
{
	static const char *bases[20];
	static unsigned bases_count = 0;
	int i, clean;
	const char *branch1, *branch2;
	struct commit *result, *h1, *h2;
	struct commit_list *ca = NULL;
	struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
	int index_fd;

	if (argv[0]) {
		int namelen = strlen(argv[0]);
		if (8 < namelen &&
		    !strcmp(argv[0] + namelen - 8, "-subtree"))
			subtree_merge = 1;
	}

	git_config(merge_config, NULL);
	if (getenv("GIT_MERGE_VERBOSITY"))
		verbosity = strtol(getenv("GIT_MERGE_VERBOSITY"), NULL, 10);

	if (argc < 4)
		die("Usage: %s <base>... -- <head> <remote> ...\n", argv[0]);

	for (i = 1; i < argc; ++i) {
		if (!strcmp(argv[i], "--"))
			break;
		if (bases_count < sizeof(bases)/sizeof(*bases))
			bases[bases_count++] = argv[i];
	}
	if (argc - i != 3) /* "--" "<head>" "<remote>" */
		die("Not handling anything other than two heads merge.");
	if (verbosity >= 5)
		buffer_output = 0;

	branch1 = argv[++i];
	branch2 = argv[++i];

	h1 = get_ref(branch1);
	h2 = get_ref(branch2);

	branch1 = better_branch_name(branch1);
	branch2 = better_branch_name(branch2);

	if (show(3))
		printf("Merging %s with %s\n", branch1, branch2);

	index_fd = hold_locked_index(lock, 1);

	for (i = 0; i < bases_count; i++) {
		struct commit *ancestor = get_ref(bases[i]);
		ca = commit_list_insert(ancestor, &ca);
	}
	clean = merge_recursive(h1, h2, branch1, branch2, ca, &result);

	if (active_cache_changed &&
	    (write_cache(index_fd, active_cache, active_nr) ||
	     commit_locked_index(lock)))
			die ("unable to write %s", get_index_file());

	return clean ? 0: 1;
}