summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--commit-graph.c18
-rw-r--r--commit-graph.h6
-rw-r--r--commit-reach.c24
3 files changed, 41 insertions, 7 deletions
diff --git a/commit-graph.c b/commit-graph.c
index b0a55ad..e9786fa 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -233,6 +233,24 @@ static int prepare_commit_graph(struct repository *r)
return !!r->objects->commit_graph;
}
+int generation_numbers_enabled(struct repository *r)
+{
+ uint32_t first_generation;
+ struct commit_graph *g;
+ if (!prepare_commit_graph(r))
+ return 0;
+
+ g = r->objects->commit_graph;
+
+ if (!g->num_commits)
+ return 0;
+
+ first_generation = get_be32(g->chunk_commit_data +
+ g->hash_len + 8) >> 2;
+
+ return !!first_generation;
+}
+
static void close_commit_graph(void)
{
free_commit_graph(the_repository->objects->commit_graph);
diff --git a/commit-graph.h b/commit-graph.h
index 76e0989..0de8f88 100644
--- a/commit-graph.h
+++ b/commit-graph.h
@@ -51,6 +51,12 @@ struct commit_graph {
struct commit_graph *load_commit_graph_one(const char *graph_file);
+/*
+ * Return 1 if and only if the repository has a commit-graph
+ * file and generation numbers are computed in that file.
+ */
+int generation_numbers_enabled(struct repository *r);
+
void write_commit_graph_reachable(const char *obj_dir, int append);
void write_commit_graph(const char *obj_dir,
struct string_list *pack_indexes,
diff --git a/commit-reach.c b/commit-reach.c
index bc522d6..c996524 100644
--- a/commit-reach.c
+++ b/commit-reach.c
@@ -277,15 +277,25 @@ int is_descendant_of(struct commit *commit, struct commit_list *with_commit)
{
if (!with_commit)
return 1;
- while (with_commit) {
- struct commit *other;
- other = with_commit->item;
- with_commit = with_commit->next;
- if (in_merge_bases(other, commit))
- return 1;
+ if (generation_numbers_enabled(the_repository)) {
+ struct commit_list *from_list = NULL;
+ int result;
+ commit_list_insert(commit, &from_list);
+ result = can_all_from_reach(from_list, with_commit, 0);
+ free_commit_list(from_list);
+ return result;
+ } else {
+ while (with_commit) {
+ struct commit *other;
+
+ other = with_commit->item;
+ with_commit = with_commit->next;
+ if (in_merge_bases(other, commit))
+ return 1;
+ }
+ return 0;
}
- return 0;
}
/*