A new option drives underlying in_merge_bases() function to determine if a commit is reachable from any of the other commits supplied on the command line. Signed-off-by: Junio C Hamano <junkio@xxxxxxx> --- Documentation/git-merge-base.txt | 13 +++++++++++- merge-base.c | 39 ++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt index 6099be2..7d4d027 100644 --- a/Documentation/git-merge-base.txt +++ b/Documentation/git-merge-base.txt @@ -8,7 +8,9 @@ git-merge-base - Finds as good a common ancestor as possible for a merge SYNOPSIS -------- +[verse] 'git-merge-base' [--all] <commit> <commit> +'git-merge-base' --check-ancestry <commit> <commit>... DESCRIPTION ----------- @@ -21,7 +23,10 @@ the parent relationship. Given a selection of equally good common ancestors it should not be relied on to decide in any particular way. -The "git-merge-base" algorithm is still in flux - use the source... +With `--check-ancestry` option, the command can be used to check +if the first commit is an ancestor of any of the remaining +commits. + OPTIONS ------- @@ -29,6 +34,12 @@ OPTIONS Output all common ancestors for the two commits instead of just one. +--check-ancestry:: + + Check if the first commit is an ancestor of any of the + remaining commits. If so, exit with status 0, otherwise + non-zero. + Author ------ Written by Linus Torvalds <torvalds@xxxxxxxx> diff --git a/merge-base.c b/merge-base.c index 385f4ba..bc478eb 100644 --- a/merge-base.c +++ b/merge-base.c @@ -2,6 +2,8 @@ #include "commit.h" static int show_all; +static const char merge_base_usage[] = +"git-merge-base [--all] <commit> <commit> | --check-ancestry <commit> <commit>..."; static int merge_base(struct commit *rev1, struct commit *rev2) { @@ -20,13 +22,37 @@ static int merge_base(struct commit *rev1, struct commit *rev2) return 0; } -static const char merge_base_usage[] = -"git-merge-base [--all] <commit-id> <commit-id>"; +static int check_ancestry(int argc, char **argv) +{ + struct commit *one, *two, **reference; + unsigned char sha1[20]; + int i; + + if (argc < 2) + usage(merge_base_usage); + if (get_sha1(argv[0], sha1)) + die("Not a valid object name %s", argv[0]); + one = lookup_commit_reference(sha1); + if (!one) + return 1; + + reference = xcalloc(argc - 1, sizeof(struct commit *)); + for (i = 1; i < argc; i++) { + if (get_sha1(argv[i], sha1)) + die("Not a valid object name %s", argv[i]); + two = lookup_commit_reference(sha1); + if (!two) + return 1; + reference[i - 1] = two; + } + return !!in_merge_bases(one, reference, argc - 1); +} int main(int argc, char **argv) { struct commit *rev1, *rev2; unsigned char rev1key[20], rev2key[20]; + int check = 0; setup_git_directory(); git_config(git_default_config); @@ -35,10 +61,19 @@ int main(int argc, char **argv) char *arg = argv[1]; if (!strcmp(arg, "-a") || !strcmp(arg, "--all")) show_all = 1; + else if (!strcmp(arg, "-c") || !strcmp(arg, "--check-ancestry")) + check = 1; else usage(merge_base_usage); argc--; argv++; } + + if (check) { + if (show_all) + die("--all and --check-ancestry are mutually incompatible"); + return check_ancestry(argc - 1, argv + 1); + } + if (argc != 3) usage(merge_base_usage); if (get_sha1(argv[1], rev1key)) -- 1.4.4.4.g564d - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html