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

[PATCH 4/6] in_merge_bases(): optimization

From
Junio C Hamano <junkio@cox.net>
Date
Jan 9, 2007, 10:41 UTC
Message-ID
<7virfgo52f.fsf@assigned-by-dhcp.cox.net>

The callers of in_merge_bases() are interested in finding out if the given commit is reachable from others, and we do not have to compute the true merge base.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 commit.c |   48 ++++++++++++++++++++++++++++++++++--------------
 1 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/commit.c b/commit.c
index 53f43e3..72f6980 100644
--- a/commit.c
+++ b/commit.c
@@ -1034,7 +1034,7 @@ static struct commit *interesting(struct commit_list *list)
 	return NULL;
 }
 
-static struct commit_list *base_traverse(struct commit_list *list)
+static struct commit_list *base_traverse(struct commit_list *list, struct commit *stop)
 {
 	struct commit_list *result = NULL;
 
@@ -1068,10 +1068,20 @@ static struct commit_list *base_traverse(struct commit_list *list)
 			p->object.flags |= flags;
 			insert_by_date(p, &list);
 		}
+		if (stop && (stop->object.flags & PARENT2)) {
+			free_commit_list(list);
+			list = NULL;
+			insert_by_date(stop, &list);
+			return list;
+		}
 	}
 
 	/* Clean up the result to remove stale ones */
 	free_commit_list(list);
+
+	if (stop)
+		return NULL;
+
 	list = result; result = NULL;
 	while (list) {
 		struct commit_list *n = list->next;
@@ -1101,7 +1111,7 @@ static struct commit_list *merge_bases(struct commit *one, struct commit *two)
 	insert_by_date(one, &list);
 	insert_by_date(two, &list);
 
-	return base_traverse(list);
+	return base_traverse(list, NULL);
 }
 
 struct commit_list *get_merge_bases(struct commit *one,
@@ -1166,20 +1176,30 @@ struct commit_list *get_merge_bases(struct commit *one,
 
 int in_merge_bases(struct commit *commit, struct commit **reference, int num)
 {
-	struct commit_list *bases, *b;
-	int ret = 0;
+	struct commit_list *result, *list;
+	int i;
 
-	if (num == 1)
-		bases = get_merge_bases(commit, *reference, 1);
-	else
-		die("not yet");
-	for (b = bases; b; b = b->next) {
-		if (!hashcmp(commit->object.sha1, b->item->object.sha1)) {
-			ret = 1;
-			break;
+	list = NULL;
+	parse_commit(commit);
+	commit->object.flags |= PARENT1;
+	insert_by_date(commit, &list);
+
+	for (i = 0; i < num; i++) {
+		struct commit *two = reference[i];
+		parse_commit(two);
+		if (!(two->object.flags & PARENT2)) {
+			two->object.flags |= PARENT2;
+			insert_by_date(two, &list);
 		}
 	}
+	result = base_traverse(list, commit);
+	i = !!result;
+	free_commit_list(result);
 
-	free_commit_list(bases);
-	return ret;
+	clear_commit_marks(commit, all_flags);
+	for (i = 0; i < num; i++) {
+		struct commit *two = reference[i];
+		clear_commit_marks(two, all_flags);
+	}
+	return i;
 }
-- 
1.4.4.4.g564d
Message 1 of 1 in “in_merge_bases(): optimization”
  1. 4/6 in_merge_bases(): optimizationJunio C Hamano, Jan 9, 2007

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.