45
return xstrfmt("%s/info/commit-graph", obj_dir);
46
}
47
48
+static char *get_split_graph_filename(const char *obj_dir,
49
+ const char *oid_hex)
50
+{
51
+ return xstrfmt("%s/info/commit-graphs/graph-%s.graph",
52
+ obj_dir,
53
+ oid_hex);
54
+}
55
+
56
+static char *get_chain_filename(const char *obj_dir)
57
+{
58
+ return xstrfmt("%s/info/commit-graphs/commit-graph-chain", obj_dir);
59
+}
60
+
61
static uint8_t oid_version(void)
62
{
63
return 1;
299
return load_commit_graph_one_fd_st(fd, &st);
300
}
301
302
+static struct commit_graph *load_commit_graph_v1(struct repository *r, const char *obj_dir)
303
+{
304
+ char *graph_name = get_commit_graph_filename(obj_dir);
305
+ struct commit_graph *g = load_commit_graph_one(graph_name);
306
+ free(graph_name);
307
+
308
+ return g;
309
+}
310
+
311
+static int add_graph_to_chain(struct commit_graph *g,
312
+ struct commit_graph *chain,
313
+ struct object_id *oids,
314
+ int n)
315
+{
316
+ struct commit_graph *cur_g = chain;
317
+
318
+ while (n) {
319
+ n--;
320
+ cur_g = cur_g->base_graph;
321
+ }
322
+
323
+ g->base_graph = chain;
324
+
325
+ if (chain)
326
+ g->num_commits_in_base = chain->num_commits + chain->num_commits_in_base;
327
+
328
+ return 1;
329
+}
330
+
331
+static struct commit_graph *load_commit_graph_chain(struct repository *r, const char *obj_dir)
332
+{
333
+ struct commit_graph *graph_chain = NULL;
334
+ struct strbuf line = STRBUF_INIT;
335
+ struct stat st;
336
+ struct object_id *oids;
337
+ int i = 0, valid = 1, count;
338
+ char *chain_name = get_chain_filename(obj_dir);
339
+ FILE *fp;
340
+ int stat_res;
341
+
342
+ fp = fopen(chain_name, "r");
343
+ stat_res = stat(chain_name, &st);
344
+ free(chain_name);
345
+
346
+ if (!fp ||
347
+ stat_res ||
348
+ st.st_size <= the_hash_algo->hexsz)
349
+ return NULL;
350
+
351
+ count = st.st_size / (the_hash_algo->hexsz + 1);
352
+ oids = xcalloc(count, sizeof(struct object_id));
353
+
354
+ for (i = 0; i < count && valid; i++) {
355
+ char *graph_name;
356
+ struct commit_graph *g;
357
+
358
+ if (strbuf_getline_lf(&line, fp) == EOF)
359
+ break;
360
+
361
+ if (get_oid_hex(line.buf, &oids[i])) {
362
+ warning(_("invalid commit-graph chain: line '%s' not a hash"),
363
+ line.buf);
364
+ valid = 0;
365
+ break;
366
+ }
367
+
368
+ graph_name = get_split_graph_filename(obj_dir, line.buf);
369
+ g = load_commit_graph_one(graph_name);
370
+ free(graph_name);
371
+
372
+ if (g && add_graph_to_chain(g, graph_chain, oids, i))
373
+ graph_chain = g;
374
+ else
375
+ valid = 0;
376
+ }
377
+
378
+ free(oids);
379
+ fclose(fp);
380
+
381
+ return graph_chain;
382
+}
383
+
384
+static struct commit_graph *read_commit_graph_one(struct repository *r, const char *obj_dir)
385
+{
386
+ struct commit_graph *g = load_commit_graph_v1(r, obj_dir);
387
+
388
+ if (!g)
389
+ g = load_commit_graph_chain(r, obj_dir);
390
+
391
+ return g;
392
+}
393
+
394
static void prepare_commit_graph_one(struct repository *r, const char *obj_dir)
395
{
291
- char *graph_name;
396
397
if (r->objects->commit_graph)
398
return;
399
296
- graph_name = get_commit_graph_filename(obj_dir);
297
- r->objects->commit_graph =
298
- load_commit_graph_one(graph_name);
299
-
300
- FREE_AND_NULL(graph_name);
400
+ r->objects->commit_graph = read_commit_graph_one(r, obj_dir);
401
}
402
403
/*