From: Derrick Stolee <dsto...@microsoft.com>

Starting with commit-graph, load commit-graph files in a
sequence as follows:

  commit-graph
  commit-graph-1
  commit-graph-2
  ...
  commit-graph-N

This creates N + 1 files in order.

Signed-off-by: Derrick Stolee <dsto...@microsoft.com>
---
 commit-graph.c | 39 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 5 deletions(-)

diff --git a/commit-graph.c b/commit-graph.c
index f790f44a9c..5f6193277a 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -45,6 +45,12 @@ char *get_commit_graph_filename(const char *obj_dir)
        return xstrfmt("%s/info/commit-graph", obj_dir);
 }
 
+static char *get_split_graph_filename(const char *obj_dir,
+                                     uint32_t split_count)
+{
+       return xstrfmt("%s/info/commit-graphs/commit-graph-%d", obj_dir, 
split_count);
+}
+
 static uint8_t oid_version(void)
 {
        return 1;
@@ -289,15 +295,31 @@ static struct commit_graph *load_commit_graph_one(const 
char *graph_file)
 static void prepare_commit_graph_one(struct repository *r, const char *obj_dir)
 {
        char *graph_name;
+       uint32_t split_count = 1;
+       struct commit_graph *g;
 
        if (r->objects->commit_graph)
                return;
 
        graph_name = get_commit_graph_filename(obj_dir);
-       r->objects->commit_graph =
-               load_commit_graph_one(graph_name);
-
+       g = load_commit_graph_one(graph_name);
        FREE_AND_NULL(graph_name);
+
+       while (g) {
+               g->base_graph = r->objects->commit_graph;
+
+               if (g->base_graph)
+                       g->num_commits_in_base = g->base_graph->num_commits +
+                                                
g->base_graph->num_commits_in_base;;
+
+               r->objects->commit_graph = g;
+
+               graph_name = get_split_graph_filename(obj_dir, split_count);
+               g = load_commit_graph_one(graph_name);
+               FREE_AND_NULL(graph_name);
+
+               split_count++;
+       }
 }
 
 /*
@@ -411,8 +433,15 @@ static struct commit_list **insert_parent_or_die(struct 
repository *r,
 
 static void fill_commit_graph_info(struct commit *item, struct commit_graph 
*g, uint32_t pos)
 {
-       const unsigned char *commit_data = g->chunk_commit_data + 
GRAPH_DATA_WIDTH * pos;
-       item->graph_pos = pos + g->num_commits_in_base;
+       const unsigned char *commit_data;
+
+       if (pos < g->num_commits_in_base) {
+               fill_commit_graph_info(item, g->base_graph, pos);
+               return;
+       }
+
+       commit_data = g->chunk_commit_data + GRAPH_DATA_WIDTH * (pos - 
g->num_commits_in_base);
+       item->graph_pos = pos;
        item->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
 }
 
-- 
gitgitgadget

Reply via email to