Merge branch 'bm/merge-base-octopus-dedup'
authorJunio C Hamano <gitster@pobox.com>
Fri, 10 Jan 2014 18:33:32 +0000 (10:33 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 10 Jan 2014 18:33:33 +0000 (10:33 -0800)
"git merge-base --octopus" used to leave cleaning up suboptimal
result to the caller, but now it does the clean-up itself.

* bm/merge-base-octopus-dedup:
merge-base --octopus: reduce the result from get_octopus_merge_bases()
merge-base: separate "--independent" codepath into its own helper

builtin/merge-base.c
t/t6010-merge-base.sh
index a2923235e1024e554b0dc937c8222282d1855065..0ecde8da30615996f54563014e4774b67812c531 100644 (file)
@@ -48,19 +48,36 @@ static struct commit *get_commit_reference(const char *arg)
        return r;
 }
 
-static int handle_octopus(int count, const char **args, int reduce, int show_all)
+static int handle_independent(int count, const char **args)
 {
        struct commit_list *revs = NULL;
        struct commit_list *result;
        int i;
 
-       if (reduce)
-               show_all = 1;
+       for (i = count - 1; i >= 0; i--)
+               commit_list_insert(get_commit_reference(args[i]), &revs);
+
+       result = reduce_heads(revs);
+       if (!result)
+               return 1;
+
+       while (result) {
+               printf("%s\n", sha1_to_hex(result->item->object.sha1));
+               result = result->next;
+       }
+       return 0;
+}
+
+static int handle_octopus(int count, const char **args, int show_all)
+{
+       struct commit_list *revs = NULL;
+       struct commit_list *result;
+       int i;
 
        for (i = count - 1; i >= 0; i--)
                commit_list_insert(get_commit_reference(args[i]), &revs);
 
-       result = reduce ? reduce_heads(revs) : get_octopus_merge_bases(revs);
+       result = reduce_heads(get_octopus_merge_bases(revs));
 
        if (!result)
                return 1;
@@ -220,8 +237,11 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix)
        if (cmdmode == 'r' && show_all)
                die("--independent cannot be used with --all");
 
-       if (cmdmode == 'r' || cmdmode == 'o')
-               return handle_octopus(argc, argv, cmdmode == 'r', show_all);
+       if (cmdmode == 'o')
+               return handle_octopus(argc, argv, show_all);
+
+       if (cmdmode == 'r')
+               return handle_independent(argc, argv);
 
        if (cmdmode == 'f') {
                if (argc < 1 || 2 < argc)
index 30a68335b3a69a8189648213606ddeb32b97d99e..39b3238da211957eeec36a9c7b911cd5942de6dd 100755 (executable)
@@ -258,4 +258,43 @@ test_expect_success 'using reflog to find the fork point' '
        test_cmp expect3 actual
 '
 
+test_expect_success 'merge-base --octopus --all for complex tree' '
+       # Best common ancestor for JE, JAA and JDD is JC
+       #             JE
+       #            / |
+       #           /  |
+       #          /   |
+       #  JAA    /    |
+       #   |\   /     |
+       #   | \  | JDD |
+       #   |  \ |/ |  |
+       #   |   JC JD  |
+       #   |    | /|  |
+       #   |    |/ |  |
+       #  JA    |  |  |
+       #   |\  /|  |  |
+       #   X JB |  X  X
+       #   \  \ | /   /
+       #    \__\|/___/
+       #        J
+       test_commit J &&
+       test_commit JB &&
+       git reset --hard J &&
+       test_commit JC &&
+       git reset --hard J &&
+       test_commit JTEMP1 &&
+       test_merge JA JB &&
+       test_merge JAA JC &&
+       git reset --hard J &&
+       test_commit JTEMP2 &&
+       test_merge JD JB &&
+       test_merge JDD JC &&
+       git reset --hard J &&
+       test_commit JTEMP3 &&
+       test_merge JE JC &&
+       git rev-parse JC >expected &&
+       git merge-base --all --octopus JAA JDD JE >actual &&
+       test_cmp expected actual
+'
+
 test_done