{"thread":{"id":"6302","subject":"[PATCH 6/6] Teach \"git-merge-base --check-ancestry\" about refs.","startedAt":"2007-01-09T10:41:30Z","lastAt":"2007-01-09T10:41:30Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"31228","messageId":"7v7ivwo52d.fsf@assigned-by-dhcp.cox.net","threadId":"6302","inReplyTo":null,"subject":"[PATCH 6/6] Teach \"git-merge-base --check-ancestry\" about refs.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-01-09T10:41:30Z","receivedAt":"2007-01-09T10:41:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"git-merge-base --all -c $commit\" is used to see if $commit is\nreachable from any ref.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n Documentation/git-merge-base.txt |    6 ++++-\n builtin-merge-base.c             |   45 ++++++++++++++++++++++++++++++++-----\n 2 files changed, 44 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt\nindex 7d4d027..21b5dd3 100644\n--- a/Documentation/git-merge-base.txt\n+++ b/Documentation/git-merge-base.txt\n@@ -10,7 +10,7 @@ SYNOPSIS\n --------\n [verse]\n 'git-merge-base' [--all] <commit> <commit>\n-'git-merge-base' --check-ancestry <commit> <commit>...\n+'git-merge-base' [--all] --check-ancestry <commit> <commit>...\n \n DESCRIPTION\n -----------\n@@ -33,6 +33,10 @@ OPTIONS\n --all::\n \tOutput all common ancestors for the two commits instead of\n \tjust one.\n++\n+When used with `--check-ancestry` option, this uses all the\n+commits that are at the tip of all refs to see if the given\n+commit is an ancestor of any of them.\n \n --check-ancestry::\n \ndiff --git a/builtin-merge-base.c b/builtin-merge-base.c\nindex fa07352..eeb8763 100644\n--- a/builtin-merge-base.c\n+++ b/builtin-merge-base.c\n@@ -1,5 +1,6 @@\n #include \"cache.h\"\n #include \"commit.h\"\n+#include \"refs.h\"\n \n static const char merge_base_usage[] =\n \"git-merge-base [--all] <commit> <commit> | --check-ancestry <commit> <commit>...\";\n@@ -21,13 +22,42 @@ static int show_merge_base(struct commit *rev1, struct commit *rev2, int show_al\n \treturn 0;\n }\n \n-static int check_ancestry(int argc, const char **argv)\n+struct add_one_ref_cb {\n+\tstruct commit ***reference;\n+\tint n;\n+};\n+\n+static int add_one_ref(const char *name, const unsigned char *sha1, int flags, void *cb_data)\n+{\n+\tstruct add_one_ref_cb *cb = (struct add_one_ref_cb *) cb_data;\n+\tstruct commit *commit = lookup_commit_reference_gently(sha1, 1);\n+\n+\tif (!commit)\n+\t\treturn 0;\n+\tcb->n++;\n+\t*cb->reference = xrealloc(*cb->reference,\n+\t\t\t\t  sizeof(struct commit *) * cb->n);\n+\t(*cb->reference)[cb->n-1] = commit;\n+\treturn 0;\n+}\n+\n+static int add_all_refs(struct commit ***reference, int n)\n+{\n+\tstruct add_one_ref_cb cb;\n+\n+\tcb.reference = reference;\n+\tcb.n = n;\n+\tfor_each_ref(add_one_ref, &cb);\n+\treturn cb.n;\n+}\n+\n+static int check_ancestry(int all, int argc, const char **argv)\n {\n \tstruct commit *one, *two, **reference;\n \tunsigned char sha1[20];\n \tint i;\n \n-\tif (argc < 2)\n+\tif (argc < 1 || (!all && argc < 2))\n \t\tusage(merge_base_usage);\n \tif (get_sha1(argv[0], sha1))\n \t\tdie(\"Not a valid object name %s\", argv[0]);\n@@ -44,7 +74,12 @@ static int check_ancestry(int argc, const char **argv)\n \t\t\treturn 1;\n \t\treference[i - 1] = two;\n \t}\n-\treturn !!in_merge_bases(one, reference, argc - 1);\n+\ti = argc - 1;\n+\n+\tif (all)\n+\t\ti = add_all_refs(&reference, i);\n+\n+\treturn !in_merge_bases(one, reference, i);\n }\n \n int cmd_merge_base(int argc, const char **argv, const char *prefix)\n@@ -68,9 +103,7 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (check) {\n-\t\tif (show_all)\n-\t\t\tdie(\"--all and --check-ancestry are mutually incompatible\");\n-\t\treturn check_ancestry(argc - 1, argv + 1);\n+\t\treturn check_ancestry(show_all, argc - 1, argv + 1);\n \t}\n \n \tif (argc != 3)\n-- \n1.4.4.4.g564d\n"}]}