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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]