summaryrefslogtreecommitdiff
path: root/merge-base.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-17 19:18:17 (GMT)
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-17 19:18:17 (GMT)
commit6683463ed6b2da9eed309c305806f9393d1ae728 (patch)
tree6d296ca7b9d8916797835771722b0c46085a6ea4 /merge-base.c
parent15000d78996db926d18dd68e6f5f5770de09cad3 (diff)
downloadgit-6683463ed6b2da9eed309c305806f9393d1ae728.zip
git-6683463ed6b2da9eed309c305806f9393d1ae728.tar.gz
git-6683463ed6b2da9eed309c305806f9393d1ae728.tar.bz2
Do a very simple "merge-base" that finds the most recent common
parent of two commits. The question of "best" commit can probably be tweaked almost arbitrarily. In particular, trying to take things like how big the tree differences are into account migt be a good idea. This one is just very simple.
Diffstat (limited to 'merge-base.c')
-rw-r--r--merge-base.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/merge-base.c b/merge-base.c
new file mode 100644
index 0000000..36ac420
--- /dev/null
+++ b/merge-base.c
@@ -0,0 +1,57 @@
+#include "cache.h"
+#include "revision.h"
+
+/*
+ * This is stupid. We could have much better heurstics, I bet.
+ */
+static int better(struct revision *new, struct revision *old)
+{
+ return new->date > old->date;
+}
+
+static struct revision *common_parent(struct revision *rev1, struct revision *rev2)
+{
+ int i;
+ struct revision *best = NULL;
+
+ mark_reachable(rev1, 1);
+ mark_reachable(rev2, 2);
+ for (i = 0; i < nr_revs ;i++) {
+ struct revision *rev = revs[i];
+ if ((rev->flags & 3) != 3)
+ continue;
+ if (!best) {
+ best = rev;
+ continue;
+ }
+ if (better(rev, best))
+ best = rev;
+ }
+ return best;
+}
+
+int main(int argc, char **argv)
+{
+ unsigned char rev1[20], rev2[20];
+ struct revision *common;
+
+ if (argc != 3 || get_sha1_hex(argv[1], rev1) || get_sha1_hex(argv[2], rev2))
+ usage("merge-base <commit1> <commit2>");
+
+ /*
+ * We will eventually want to include a revision cache file
+ * that "rev-tree.c" has generated, since this is going to
+ * otherwise be quite expensive for big trees..
+ *
+ * That's some time off, though, and in the meantime we know
+ * that we have a solution to the eventual expense.
+ */
+ parse_commit(rev1);
+ parse_commit(rev2);
+
+ common = common_parent(lookup_rev(rev1), lookup_rev(rev2));
+ if (!common)
+ die("no common parent found");
+ printf("%s\n", sha1_to_hex(common->sha1));
+ return 0;
+}