Skip to content

Commit 501e3ba

Browse files
keyu98ttaylorr
authored andcommitted
merge-tree.c: allow specifying the merge-base when --stdin is passed
The previous commit added a `--merge-base` option in order to allow using a specified merge-base for the merge. Extend the input accepted by `--stdin` to also allow a specified merge-base with each merge requested. For example: printf "<b3> -- <b1> <b2>" | git merge-tree --stdin does a merge of b1 and b2, and uses b3 as the merge-base. Signed-off-by: Kyle Zhao <[email protected]> Signed-off-by: Taylor Blau <[email protected]>
1 parent 66265a6 commit 501e3ba

File tree

3 files changed

+67
-3
lines changed

3 files changed

+67
-3
lines changed

Documentation/git-merge-tree.txt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ OPTIONS
6666

6767
--merge-base=<commit>::
6868
Instead of finding the merge-bases for <branch1> and <branch2>,
69-
specify a merge-base for the merge.
69+
specify a merge-base for the merge. This option is incompatible
70+
with `--stdin`.
7071

7172
[[OUTPUT]]
7273
OUTPUT
@@ -220,6 +221,17 @@ with linkgit:git-merge[1]:
220221
* any messages that would have been printed to stdout (the
221222
<<IM,Informational messages>>)
222223

224+
INPUT FORMAT
225+
------------
226+
'git merge-tree --stdin' input format is fully text based. Each line
227+
has this format:
228+
229+
[<base-commit> -- ]<branch1> <branch2>
230+
231+
If one line is separated by `--`, the string before the separator is
232+
used for specifying a merge-base for the merge and the string after
233+
the separator describes the branches to be merged.
234+
223235
MISTAKES TO AVOID
224236
-----------------
225237

builtin/merge-tree.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,12 +557,29 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)
557557
while (strbuf_getline_lf(&buf, stdin) != EOF) {
558558
struct strbuf **split;
559559
int result;
560+
const char *input_merge_base = NULL;
560561

561562
split = strbuf_split(&buf, ' ');
562-
if (!split[0] || !split[1] || split[2])
563+
if (!split[0] || !split[1])
563564
die(_("malformed input line: '%s'."), buf.buf);
564565
strbuf_rtrim(split[0]);
565-
result = real_merge(&o, merge_base, split[0]->buf, split[1]->buf, prefix);
566+
strbuf_rtrim(split[1]);
567+
568+
/* parse the merge-base */
569+
if (!strcmp(split[1]->buf, "--")) {
570+
input_merge_base = split[0]->buf;
571+
}
572+
573+
if (input_merge_base && split[2] && split[3] && !split[4]) {
574+
strbuf_rtrim(split[2]);
575+
strbuf_rtrim(split[3]);
576+
result = real_merge(&o, input_merge_base, split[2]->buf, split[3]->buf, prefix);
577+
} else if (!input_merge_base && !split[2]) {
578+
result = real_merge(&o, NULL, split[0]->buf, split[1]->buf, prefix);
579+
} else {
580+
die(_("malformed input line: '%s'."), buf.buf);
581+
}
582+
566583
if (result < 0)
567584
die(_("merging cannot continue; got unclean result of %d"), result);
568585
strbuf_list_free(split);

t/t4301-merge-tree-write-tree.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,13 @@ test_expect_success '--stdin with both a successful and a conflicted merge' '
860860
test_cmp expect actual
861861
'
862862

863+
864+
test_expect_success '--merge-base is incompatible with --stdin' '
865+
test_must_fail git merge-tree --merge-base=side1 --stdin 2>expect &&
866+
867+
grep "^fatal: --merge-base is incompatible with --stdin" expect
868+
'
869+
863870
# specify merge-base as parent of branch2
864871
# git merge-tree --write-tree --merge-base=c2 c1 c3
865872
# Commit c1: add file1
@@ -887,4 +894,32 @@ test_expect_success 'specify merge-base as parent of branch2' '
887894
test_cmp expect actual
888895
'
889896

897+
# Since the earlier tests have verified that individual merge-tree calls
898+
# are doing the right thing, this test case is only used to verify that
899+
# we can also trigger merges via --stdin, and that when we do we get
900+
# the same answer as running a bunch of separate merges.
901+
902+
test_expect_success 'check the input format when --stdin is passed' '
903+
test_when_finished "rm -rf repo" &&
904+
git init repo &&
905+
test_commit -C repo c1 &&
906+
test_commit -C repo c2 &&
907+
test_commit -C repo c3 &&
908+
printf "c1 c3\nc2 -- c1 c3\nc2 c3" | git -C repo merge-tree --stdin >actual &&
909+
910+
printf "1\0" >expect &&
911+
git -C repo merge-tree --write-tree -z c1 c3 >>expect &&
912+
printf "\0" >>expect &&
913+
914+
printf "1\0" >>expect &&
915+
git -C repo merge-tree --write-tree -z --merge-base=c2 c1 c3 >>expect &&
916+
printf "\0" >>expect &&
917+
918+
printf "1\0" >>expect &&
919+
git -C repo merge-tree --write-tree -z c2 c3 >>expect &&
920+
printf "\0" >>expect &&
921+
922+
test_cmp expect actual
923+
'
924+
890925
test_done

0 commit comments

Comments
 (0)