threads / patch / 6304

patch, 6 partsgit-merge-base: --check-ancestry option

Subject: [PATCH 3/6] git-merge-base: --check-ancestry option

## tl;dr

One message between Jan 9, 2007 and Jan 9, 2007. Diffs are folded; open one to read it.

replies: 0people: 1as markdown or json

Junio C Hamano· Jan 9, 2007, 10:41 UTC · lore

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@cox.net>
---
 Documentation/git-merge-base.txt |   13 +++++++++++-
 merge-base.c                     |   39 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 49 insertions(+), 3 deletions(-)
Show changes to 2 files +49 −3

Documentation/git-merge-base.txt, merge-base.c

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@osdl.org>
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

← back to recent threads