git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[5/5] Switch implementations of merge-base, port to parsing

From
Daniel Barkalow <barkalow@iabervon.org>
Date
Apr 18, 2005, 02:42 UTC
Message-ID
<Pine.LNX.4.21.0504172240250.30848-100000@iabervon.org>
In-Reply-To
<Pine.LNX.4.21.0504172229240.30848-100000@iabervon.org>

This switches to my implementation of merge-base, but with the new parsing library.

Signed-Off-By: Daniel Barkalow <barkalow@iabervon.org>
Index: Makefile
===================================================================
--- 108bfb69c14c55c3c6e30a298307390c82cf1b3b/Makefile  (mode:100644 sha1:affc0e96030d4514f8306ee29020ca6bb320648f)
+++ 1172a9b8f45b2fd640985595cc5258db3b027828/Makefile  (mode:100644 sha1:c8908268d3c2253d3905671de5cabe4c84674128)
@@ -64,8 +64,8 @@
 ls-tree: ls-tree.o read-cache.o
 	$(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)
 
-merge-base: merge-base.o read-cache.o
-	$(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o $(LIBS)
+merge-base: merge-base.o read-cache.o object.o commit.o tree.o blob.o
+	$(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
 
 read-cache.o: cache.h
 show-diff.o: cache.h
Index: merge-base.c
===================================================================
--- 108bfb69c14c55c3c6e30a298307390c82cf1b3b/merge-base.c  (mode:100644 sha1:c98cad0befcf7e04fcc329d9bb7cb550506a4574)
+++ 1172a9b8f45b2fd640985595cc5258db3b027828/merge-base.c  (mode:100644 sha1:414ff419c679dba122b2f21b698c1e2c8abdd965)
@@ -1,57 +1,95 @@
+#include <stdlib.h>
 #include "cache.h"
-#include "revision.h"
+#include "commit.h"
 
-/*
- * This is stupid. We could have much better heurstics, I bet.
- */
-static int better(struct revision *new, struct revision *old)
+static struct commit *process_list(struct commit_list **list_p, int this_mark,
+				   int other_mark)
 {
-	return new->date > old->date;
+	struct commit_list *parent, *temp;
+	struct commit_list *posn = *list_p;
+	*list_p = NULL;
+	while (posn) {
+		parse_commit(posn->item);
+		if (posn->item->object.flags & this_mark) {
+			/*
+			  printf("%d already seen %s %x\n",
+			  this_mark
+			  sha1_to_hex(posn->parent->sha1),
+			  posn->parent->flags);
+			*/
+			/* do nothing; this indicates that this side
+			 * split and reformed, and we only need to
+			 * mark it once.
+			 */
+		} else if (posn->item->object.flags & other_mark) {
+			return posn->item;
+		} else {
+			/*
+			  printf("%d based on %s\n",
+			  this_mark,
+			  sha1_to_hex(posn->parent->sha1));
+			*/
+			posn->item->object.flags |= this_mark;
+			
+			parent = posn->item->parents;
+			while (parent) {
+				temp = malloc(sizeof(struct commit_list));
+				temp->next = *list_p;
+				temp->item = parent->item;
+				*list_p = temp;
+				parent = parent->next;
+			}
+		}
+		posn = posn->next;
+	}
+	return NULL;
 }
 
-static struct revision *common_parent(struct revision *rev1, struct revision *rev2)
+struct commit *common_ancestor(struct commit *rev1, struct commit *rev2)
 {
-	int i;
-	struct revision *best = NULL;
+	struct commit_list *rev1list = malloc(sizeof(struct commit_list));
+	struct commit_list *rev2list = malloc(sizeof(struct commit_list));
+
+	rev1list->item = rev1;
+	rev1list->next = NULL;
+
+	rev2list->item = rev2;
+	rev2list->next = 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;
+	while (rev1list || rev2list) {
+		struct commit *ret;
+		ret = process_list(&rev1list, 0x1, 0x2);
+		if (ret) {
+			/* XXXX free lists */
+			return ret;
+		}
+		ret = process_list(&rev2list, 0x2, 0x1);
+		if (ret) {
+			/* XXXX free lists */
+			return ret;
 		}
-		if (better(rev, best))
-			best = rev;
 	}
-	return best;
+	return NULL;
 }
 
 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>");
+	struct commit *rev1, *rev2, *ret;
+	unsigned char rev1key[20], rev2key[20];
 
-	/*
-	 * 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;
+	if (argc != 3 ||
+	    get_sha1_hex(argv[1], rev1key) ||
+	    get_sha1_hex(argv[2], rev2key)) {
+		usage("merge-base <commit-id> <commit-id>");
+	}
+	rev1 = lookup_commit(rev1key);
+	rev2 = lookup_commit(rev2key);
+	ret = common_ancestor(rev1, rev2);
+	if (ret) {
+		printf("%s\n", sha1_to_hex(ret->object.sha1));
+		return 0;
+	} else {
+		return 1;
+	}
+	
 }
Previous: Daniel BarkalowNext: Linus Torvalds
Message 9 of 16 in “[RFC] General object parsing”
  1. Daniel BarkalowApr 18, 2005
  2. Linus TorvaldsApr 18, 2005
  3. Daniel BarkalowApr 18, 2005
  4. 0/5 Parsers for git objects, porting some programsDaniel Barkalow, Apr 18, 2005
  5. 1/5 Header files for object parsingDaniel Barkalow, Apr 18, 2005
  6. 2/5 Implementations of parsing functionsDaniel Barkalow, Apr 18, 2005
  7. 3/5 Port rev-tree to parsing functionsDaniel Barkalow, Apr 18, 2005
  8. 4/5 Port fsck-cache to use parsing functionsDaniel Barkalow, Apr 18, 2005
  9. 5/5 Switch implementations of merge-base, port to parsingDaniel Barkalow, Apr 18, 2005
  10. Linus TorvaldsApr 18, 2005
  11. Daniel BarkalowApr 18, 2005
  12. Junio C HamanoApr 19, 2005
  13. Daniel BarkalowApr 19, 2005
  14. Daniel BarkalowApr 19, 2005
  15. Daniel BarkalowApr 18, 2005
  16. David WoodhouseApr 18, 2005

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.