summaryrefslogtreecommitdiff
path: root/commit.c
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2012-08-30 14:39:03 -0700
committerLibravatar Junio C Hamano <gitster@pobox.com>2012-08-30 17:25:57 -0700
commitda1f515641f4853a6b7c4710392796ed08efaa6f (patch)
tree869a479c1bcb972f0d81ca622df5174588b67b60 /commit.c
parentin_merge_bases(): omit unnecessary redundant common ancestor reduction (diff)
downloadtgif-da1f515641f4853a6b7c4710392796ed08efaa6f.tar.xz
merge_bases_many(): split out the logic to paint history
Introduce a new helper function paint_down_to_common() that takes the same parameters as merge_bases_many(), but without the first optimization of not painting anything when "one" is one of the "twos" (or vice versa), and the last clean-up of removing the common ancestor that is known to be an ancestor of another common one. This way, the caller of the new function could tell if "one" is reachable from any of the "twos" by simply looking at the flag bits of "one". If (and only if) it is painted in PARENT2, it is reachable from one of the "twos". Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'commit.c')
-rw-r--r--commit.c47
1 files changed, 28 insertions, 19 deletions
diff --git a/commit.c b/commit.c
index 12e5396e4c..0058fa5b43 100644
--- a/commit.c
+++ b/commit.c
@@ -581,28 +581,12 @@ static struct commit *interesting(struct commit_list *list)
return NULL;
}
-static struct commit_list *merge_bases_many(struct commit *one, int n, struct commit **twos)
+static struct commit_list *paint_down_to_common(struct commit *one, int n, struct commit **twos)
{
struct commit_list *list = NULL;
struct commit_list *result = NULL;
int i;
- for (i = 0; i < n; i++) {
- if (one == twos[i])
- /*
- * We do not mark this even with RESULT so we do not
- * have to clean it up.
- */
- return commit_list_insert(one, &result);
- }
-
- if (parse_commit(one))
- return NULL;
- for (i = 0; i < n; i++) {
- if (parse_commit(twos[i]))
- return NULL;
- }
-
one->object.flags |= PARENT1;
commit_list_insert_by_date(one, &list);
for (i = 0; i < n; i++) {
@@ -643,9 +627,34 @@ static struct commit_list *merge_bases_many(struct commit *one, int n, struct co
}
}
- /* Clean up the result to remove stale ones */
free_commit_list(list);
- list = result; result = NULL;
+ return result;
+}
+
+static struct commit_list *merge_bases_many(struct commit *one, int n, struct commit **twos)
+{
+ struct commit_list *list = NULL;
+ struct commit_list *result = NULL;
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if (one == twos[i])
+ /*
+ * We do not mark this even with RESULT so we do not
+ * have to clean it up.
+ */
+ return commit_list_insert(one, &result);
+ }
+
+ if (parse_commit(one))
+ return NULL;
+ for (i = 0; i < n; i++) {
+ if (parse_commit(twos[i]))
+ return NULL;
+ }
+
+ list = paint_down_to_common(one, n, twos);
+
while (list) {
struct commit_list *next = list->next;
if (!(list->item->object.flags & STALE))