[PATCH 6/6] Teach "git-merge-base --check-ancestry" about refs.

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

 



"git-merge-base --all -c $commit" is used to see if $commit is
reachable from any ref.

Signed-off-by: Junio C Hamano <junkio@xxxxxxx>
---
 Documentation/git-merge-base.txt |    6 ++++-
 builtin-merge-base.c             |   45 ++++++++++++++++++++++++++++++++-----
 2 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt
index 7d4d027..21b5dd3 100644
--- a/Documentation/git-merge-base.txt
+++ b/Documentation/git-merge-base.txt
@@ -10,7 +10,7 @@ SYNOPSIS
 --------
 [verse]
 'git-merge-base' [--all] <commit> <commit>
-'git-merge-base' --check-ancestry <commit> <commit>...
+'git-merge-base' [--all] --check-ancestry <commit> <commit>...
 
 DESCRIPTION
 -----------
@@ -33,6 +33,10 @@ OPTIONS
 --all::
 	Output all common ancestors for the two commits instead of
 	just one.
++
+When used with `--check-ancestry` option, this uses all the
+commits that are at the tip of all refs to see if the given
+commit is an ancestor of any of them.
 
 --check-ancestry::
 
diff --git a/builtin-merge-base.c b/builtin-merge-base.c
index fa07352..eeb8763 100644
--- a/builtin-merge-base.c
+++ b/builtin-merge-base.c
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "commit.h"
+#include "refs.h"
 
 static const char merge_base_usage[] =
 "git-merge-base [--all] <commit> <commit> | --check-ancestry <commit> <commit>...";
@@ -21,13 +22,42 @@ static int show_merge_base(struct commit *rev1, struct commit *rev2, int show_al
 	return 0;
 }
 
-static int check_ancestry(int argc, const char **argv)
+struct add_one_ref_cb {
+	struct commit ***reference;
+	int n;
+};
+
+static int add_one_ref(const char *name, const unsigned char *sha1, int flags, void *cb_data)
+{
+	struct add_one_ref_cb *cb = (struct add_one_ref_cb *) cb_data;
+	struct commit *commit = lookup_commit_reference_gently(sha1, 1);
+
+	if (!commit)
+		return 0;
+	cb->n++;
+	*cb->reference = xrealloc(*cb->reference,
+				  sizeof(struct commit *) * cb->n);
+	(*cb->reference)[cb->n-1] = commit;
+	return 0;
+}
+
+static int add_all_refs(struct commit ***reference, int n)
+{
+	struct add_one_ref_cb cb;
+
+	cb.reference = reference;
+	cb.n = n;
+	for_each_ref(add_one_ref, &cb);
+	return cb.n;
+}
+
+static int check_ancestry(int all, int argc, const char **argv)
 {
 	struct commit *one, *two, **reference;
 	unsigned char sha1[20];
 	int i;
 
-	if (argc < 2)
+	if (argc < 1 || (!all && argc < 2))
 		usage(merge_base_usage);
 	if (get_sha1(argv[0], sha1))
 		die("Not a valid object name %s", argv[0]);
@@ -44,7 +74,12 @@ static int check_ancestry(int argc, const char **argv)
 			return 1;
 		reference[i - 1] = two;
 	}
-	return !!in_merge_bases(one, reference, argc - 1);
+	i = argc - 1;
+
+	if (all)
+		i = add_all_refs(&reference, i);
+
+	return !in_merge_bases(one, reference, i);
 }
 
 int cmd_merge_base(int argc, const char **argv, const char *prefix)
@@ -68,9 +103,7 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix)
 	}
 
 	if (check) {
-		if (show_all)
-			die("--all and --check-ancestry are mutually incompatible");
-		return check_ancestry(argc - 1, argv + 1);
+		return check_ancestry(show_all, argc - 1, argv + 1);
 	}
 
 	if (argc != 3)
-- 
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]