1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-18 20:36:15 +02:00

merge-tree: accept 3 trees as arguments

When specifying a merge base explicitly, there is actually no good
reason why the inputs need to be commits: that's only needed if the
merge base has to be deduced from the commit graph.

This commit is best viewed with `--color-moved
--color-moved-ws=allow-indentation-change`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Johannes Schindelin 2024-01-28 20:34:22 +00:00 committed by Junio C Hamano
parent 564d0252ca
commit 5f43cf5b2e
3 changed files with 35 additions and 18 deletions

View File

@ -64,10 +64,13 @@ OPTIONS
share no common history. This flag can be given to override that share no common history. This flag can be given to override that
check and make the merge proceed anyway. check and make the merge proceed anyway.
--merge-base=<commit>:: --merge-base=<tree-ish>::
Instead of finding the merge-bases for <branch1> and <branch2>, Instead of finding the merge-bases for <branch1> and <branch2>,
specify a merge-base for the merge, and specifying multiple bases is specify a merge-base for the merge, and specifying multiple bases is
currently not supported. This option is incompatible with `--stdin`. currently not supported. This option is incompatible with `--stdin`.
+
As the merge-base is provided directly, <branch1> and <branch2> do not need
to specify commits; trees are enough.
[[OUTPUT]] [[OUTPUT]]
OUTPUT OUTPUT

View File

@ -430,35 +430,43 @@ static int real_merge(struct merge_tree_options *o,
struct merge_options opt; struct merge_options opt;
copy_merge_options(&opt, &o->merge_options); copy_merge_options(&opt, &o->merge_options);
parent1 = get_merge_parent(branch1);
if (!parent1)
help_unknown_ref(branch1, "merge-tree",
_("not something we can merge"));
parent2 = get_merge_parent(branch2);
if (!parent2)
help_unknown_ref(branch2, "merge-tree",
_("not something we can merge"));
opt.show_rename_progress = 0; opt.show_rename_progress = 0;
opt.branch1 = branch1; opt.branch1 = branch1;
opt.branch2 = branch2; opt.branch2 = branch2;
if (merge_base) { if (merge_base) {
struct commit *base_commit;
struct tree *base_tree, *parent1_tree, *parent2_tree; struct tree *base_tree, *parent1_tree, *parent2_tree;
base_commit = lookup_commit_reference_by_name(merge_base); /*
if (!base_commit) * We actually only need the trees because we already
die(_("could not lookup commit '%s'"), merge_base); * have a merge base.
*/
struct object_id base_oid, head_oid, merge_oid;
if (repo_get_oid_treeish(the_repository, merge_base, &base_oid))
die(_("could not parse as tree '%s'"), merge_base);
base_tree = parse_tree_indirect(&base_oid);
if (repo_get_oid_treeish(the_repository, branch1, &head_oid))
die(_("could not parse as tree '%s'"), branch1);
parent1_tree = parse_tree_indirect(&head_oid);
if (repo_get_oid_treeish(the_repository, branch2, &merge_oid))
die(_("could not parse as tree '%s'"), branch2);
parent2_tree = parse_tree_indirect(&merge_oid);
opt.ancestor = merge_base; opt.ancestor = merge_base;
base_tree = repo_get_commit_tree(the_repository, base_commit);
parent1_tree = repo_get_commit_tree(the_repository, parent1);
parent2_tree = repo_get_commit_tree(the_repository, parent2);
merge_incore_nonrecursive(&opt, base_tree, parent1_tree, parent2_tree, &result); merge_incore_nonrecursive(&opt, base_tree, parent1_tree, parent2_tree, &result);
} else { } else {
parent1 = get_merge_parent(branch1);
if (!parent1)
help_unknown_ref(branch1, "merge-tree",
_("not something we can merge"));
parent2 = get_merge_parent(branch2);
if (!parent2)
help_unknown_ref(branch2, "merge-tree",
_("not something we can merge"));
/* /*
* Get the merge bases, in reverse order; see comment above * Get the merge bases, in reverse order; see comment above
* merge_incore_recursive in merge-ort.h * merge_incore_recursive in merge-ort.h

View File

@ -945,4 +945,10 @@ test_expect_success 'check the input format when --stdin is passed' '
test_cmp expect actual test_cmp expect actual
' '
test_expect_success '--merge-base with tree OIDs' '
git merge-tree --merge-base=side1^ side1 side3 >with-commits &&
git merge-tree --merge-base=side1^^{tree} side1^{tree} side3^{tree} >with-trees &&
test_cmp with-commits with-trees
'
test_done test_done