On Fri, Mar 18, 2016 at 1:21 PM, Junio C Hamano <gitster@xxxxxxxxx> wrote: > While it makes sense to allow merging unrelated histories of two > projects that started independently into one, in the way "gitk" was > merged to "git" itself aka "the coolest merge ever", such a merge is > still an unusual event. Worse, if somebody creates an independent > history by starting from a tarball of an established project and > sends a pull request to the original project, "git merge" however > happily creates such a merge without any sign of something unusual > is happening. > > Teach "git merge" to refuse to create such a merge by default, > unless the user passes a new "--allow-unrelated-histories" option to > tell it that the user is aware that two unrelated projects are > merged. Heh. I had a separate set of patches for you, but hadn't sent them out because of the other test failures (which you also worked out). Mine was slightly different, I just went with a "unrelated" merge option. I'll attach my two patches anyway, if for no other reason than the fact that I actually wrote a new test for this. Feel free to ignore my patches, they have nothing really different from yours, just slightly different implementation. Linus
From 0f3e4a9294eeda6799e3e50e28809133233126db Mon Sep 17 00:00:00 2001 From: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Date: Fri, 18 Mar 2016 12:46:06 -0700 Subject: [PATCH 1/2] t3035: test merging of unrelated branches Right now this succeeds, and the test actually verifies that behavior. Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> --- t/t3035-merge-recursive-across-project.sh | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100755 t/t3035-merge-recursive-across-project.sh diff --git a/t/t3035-merge-recursive-across-project.sh b/t/t3035-merge-recursive-across-project.sh new file mode 100755 index 000000000000..b5d614db6b08 --- /dev/null +++ b/t/t3035-merge-recursive-across-project.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +test_description='merge-recursive with unrelated projects + +Test rename detection by examining rename/delete conflicts. + + * A: file A + + * B: file B +' + +. ./test-lib.sh + +test_expect_success 'setup repository' \ + 'echo Hello >A && + git add A && + git commit -m "Branch A" A && + git branch A && + git mv A B && + echo Hi >B && + git commit -m "Branch B" --amend B && + git branch B' + +test_expect_success 'merge unrelated branches' \ + 'git checkout -b merged A && + git merge B' + +test_done -- 2.8.0.rc3.9.g44915db
From cd6b2388c73f37b3dd6180d9a42993fd219ebb31 Mon Sep 17 00:00:00 2001 From: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Date: Fri, 18 Mar 2016 12:57:30 -0700 Subject: [PATCH 2/2] merge: fail merging of unrelated branches Add test for this, and add the "unrelated" merge option to allow it to succeed. Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> --- merge-recursive.c | 6 ++++++ merge-recursive.h | 1 + t/t3035-merge-recursive-across-project.sh | 7 +++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index b880ae50e7ee..92779db0bbe6 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1927,6 +1927,9 @@ int merge_recursive(struct merge_options *o, /* if there is no common ancestor, use an empty tree */ struct tree *tree; + if (!o->allow_unrelated) + die(_("will not merge unrelated branches")); + tree = lookup_tree(EMPTY_TREE_SHA1_BIN); merged_common_ancestors = make_virtual_commit(tree, "ancestor"); } @@ -2039,6 +2042,7 @@ void init_merge_options(struct merge_options *o) memset(o, 0, sizeof(struct merge_options)); o->verbosity = 2; o->buffer_output = 1; + o->allow_unrelated = 0; o->diff_rename_limit = -1; o->merge_rename_limit = -1; o->renormalize = 0; @@ -2092,6 +2096,8 @@ int parse_merge_opt(struct merge_options *o, const char *s) o->renormalize = 1; else if (!strcmp(s, "no-renormalize")) o->renormalize = 0; + else if (!strcmp(s, "unrelated")) + o->allow_unrelated = 1; else if (!strcmp(s, "no-renames")) o->detect_rename = 0; else if (!strcmp(s, "find-renames")) { diff --git a/merge-recursive.h b/merge-recursive.h index 52f0201f68a3..19eb52eeb732 100644 --- a/merge-recursive.h +++ b/merge-recursive.h @@ -15,6 +15,7 @@ struct merge_options { const char *subtree_shift; unsigned buffer_output : 1; unsigned renormalize : 1; + unsigned allow_unrelated : 1; long xdl_opts; int verbosity; int detect_rename; diff --git a/t/t3035-merge-recursive-across-project.sh b/t/t3035-merge-recursive-across-project.sh index b5d614db6b08..87902f1c8f66 100755 --- a/t/t3035-merge-recursive-across-project.sh +++ b/t/t3035-merge-recursive-across-project.sh @@ -21,8 +21,11 @@ test_expect_success 'setup repository' \ git commit -m "Branch B" --amend B && git branch B' -test_expect_success 'merge unrelated branches' \ +test_expect_success 'fail merging of unrelated branches' \ 'git checkout -b merged A && - git merge B' + test_must_fail git merge B' + +test_expect_success 'explicitly merge unrelated branches' \ + 'git merge -Xunrelated B' test_done -- 2.8.0.rc3.9.g44915db