Git fork
1#define USE_THE_REPOSITORY_VARIABLE
2#define DISABLE_SIGN_COMPARE_WARNINGS
3
4#include "git-compat-util.h"
5#include "config.h"
6#include "csum-file.h"
7#include "environment.h"
8#include "gettext.h"
9#include "hex.h"
10#include "lockfile.h"
11#include "packfile.h"
12#include "commit.h"
13#include "object.h"
14#include "refs.h"
15#include "hash-lookup.h"
16#include "commit-graph.h"
17#include "odb.h"
18#include "oid-array.h"
19#include "path.h"
20#include "alloc.h"
21#include "hashmap.h"
22#include "replace-object.h"
23#include "progress.h"
24#include "bloom.h"
25#include "commit-slab.h"
26#include "shallow.h"
27#include "json-writer.h"
28#include "trace2.h"
29#include "tree.h"
30#include "chunk-format.h"
31
32void git_test_write_commit_graph_or_die(void)
33{
34 int flags = 0;
35 if (!git_env_bool(GIT_TEST_COMMIT_GRAPH, 0))
36 return;
37
38 if (git_env_bool(GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS, 0))
39 flags = COMMIT_GRAPH_WRITE_BLOOM_FILTERS;
40
41 if (write_commit_graph_reachable(the_repository->objects->sources,
42 flags, NULL))
43 die("failed to write commit-graph under GIT_TEST_COMMIT_GRAPH");
44}
45
46#define GRAPH_SIGNATURE 0x43475048 /* "CGPH" */
47#define GRAPH_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */
48#define GRAPH_CHUNKID_OIDLOOKUP 0x4f49444c /* "OIDL" */
49#define GRAPH_CHUNKID_DATA 0x43444154 /* "CDAT" */
50#define GRAPH_CHUNKID_GENERATION_DATA 0x47444132 /* "GDA2" */
51#define GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW 0x47444f32 /* "GDO2" */
52#define GRAPH_CHUNKID_EXTRAEDGES 0x45444745 /* "EDGE" */
53#define GRAPH_CHUNKID_BLOOMINDEXES 0x42494458 /* "BIDX" */
54#define GRAPH_CHUNKID_BLOOMDATA 0x42444154 /* "BDAT" */
55#define GRAPH_CHUNKID_BASE 0x42415345 /* "BASE" */
56
57#define GRAPH_DATA_WIDTH (the_hash_algo->rawsz + 16)
58
59#define GRAPH_VERSION_1 0x1
60#define GRAPH_VERSION GRAPH_VERSION_1
61
62#define GRAPH_EXTRA_EDGES_NEEDED 0x80000000
63#define GRAPH_EDGE_LAST_MASK 0x7fffffff
64#define GRAPH_PARENT_NONE 0x70000000
65
66#define GRAPH_LAST_EDGE 0x80000000
67
68#define GRAPH_HEADER_SIZE 8
69#define GRAPH_FANOUT_SIZE (4 * 256)
70#define GRAPH_MIN_SIZE (GRAPH_HEADER_SIZE + 4 * CHUNK_TOC_ENTRY_SIZE \
71 + GRAPH_FANOUT_SIZE + the_hash_algo->rawsz)
72
73#define CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW (1ULL << 31)
74
75/* Remember to update object flag allocation in object.h */
76#define REACHABLE (1u<<15)
77
78define_commit_slab(topo_level_slab, uint32_t);
79
80/* Keep track of the order in which commits are added to our list. */
81define_commit_slab(commit_pos, int);
82static struct commit_pos commit_pos = COMMIT_SLAB_INIT(1, commit_pos);
83
84static void set_commit_pos(struct repository *r, const struct object_id *oid)
85{
86 static int32_t max_pos;
87 struct commit *commit = lookup_commit(r, oid);
88
89 if (!commit)
90 return; /* should never happen, but be lenient */
91
92 *commit_pos_at(&commit_pos, commit) = max_pos++;
93}
94
95static int commit_pos_cmp(const void *va, const void *vb)
96{
97 const struct commit *a = *(const struct commit **)va;
98 const struct commit *b = *(const struct commit **)vb;
99 return commit_pos_at(&commit_pos, a) -
100 commit_pos_at(&commit_pos, b);
101}
102
103define_commit_slab(commit_graph_data_slab, struct commit_graph_data);
104static struct commit_graph_data_slab commit_graph_data_slab =
105 COMMIT_SLAB_INIT(1, commit_graph_data_slab);
106
107static int get_configured_generation_version(struct repository *r)
108{
109 int version = 2;
110 repo_config_get_int(r, "commitgraph.generationversion", &version);
111 return version;
112}
113
114uint32_t commit_graph_position(const struct commit *c)
115{
116 struct commit_graph_data *data =
117 commit_graph_data_slab_peek(&commit_graph_data_slab, c);
118
119 return data ? data->graph_pos : COMMIT_NOT_FROM_GRAPH;
120}
121
122timestamp_t commit_graph_generation(const struct commit *c)
123{
124 struct commit_graph_data *data =
125 commit_graph_data_slab_peek(&commit_graph_data_slab, c);
126
127 if (data && data->generation)
128 return data->generation;
129
130 return GENERATION_NUMBER_INFINITY;
131}
132
133static timestamp_t commit_graph_generation_from_graph(const struct commit *c)
134{
135 struct commit_graph_data *data =
136 commit_graph_data_slab_peek(&commit_graph_data_slab, c);
137
138 if (!data || data->graph_pos == COMMIT_NOT_FROM_GRAPH)
139 return GENERATION_NUMBER_INFINITY;
140 return data->generation;
141}
142
143static struct commit_graph_data *commit_graph_data_at(const struct commit *c)
144{
145 unsigned int i, nth_slab;
146 struct commit_graph_data *data =
147 commit_graph_data_slab_peek(&commit_graph_data_slab, c);
148
149 if (data)
150 return data;
151
152 nth_slab = c->index / commit_graph_data_slab.slab_size;
153 data = commit_graph_data_slab_at(&commit_graph_data_slab, c);
154
155 /*
156 * commit-slab initializes elements with zero, overwrite this with
157 * COMMIT_NOT_FROM_GRAPH for graph_pos.
158 *
159 * We avoid initializing generation with checking if graph position
160 * is not COMMIT_NOT_FROM_GRAPH.
161 */
162 for (i = 0; i < commit_graph_data_slab.slab_size; i++) {
163 commit_graph_data_slab.slab[nth_slab][i].graph_pos =
164 COMMIT_NOT_FROM_GRAPH;
165 }
166
167 return data;
168}
169
170/*
171 * Should be used only while writing commit-graph as it compares
172 * generation value of commits by directly accessing commit-slab.
173 */
174static int commit_gen_cmp(const void *va, const void *vb)
175{
176 const struct commit *a = *(const struct commit **)va;
177 const struct commit *b = *(const struct commit **)vb;
178
179 const timestamp_t generation_a = commit_graph_data_at(a)->generation;
180 const timestamp_t generation_b = commit_graph_data_at(b)->generation;
181 /* lower generation commits first */
182 if (generation_a < generation_b)
183 return -1;
184 else if (generation_a > generation_b)
185 return 1;
186
187 /* use date as a heuristic when generations are equal */
188 if (a->date < b->date)
189 return -1;
190 else if (a->date > b->date)
191 return 1;
192 return 0;
193}
194
195char *get_commit_graph_filename(struct odb_source *source)
196{
197 return xstrfmt("%s/info/commit-graph", source->path);
198}
199
200static char *get_split_graph_filename(struct odb_source *source,
201 const char *oid_hex)
202{
203 return xstrfmt("%s/info/commit-graphs/graph-%s.graph", source->path,
204 oid_hex);
205}
206
207char *get_commit_graph_chain_filename(struct odb_source *source)
208{
209 return xstrfmt("%s/info/commit-graphs/commit-graph-chain", source->path);
210}
211
212static struct commit_graph *alloc_commit_graph(void)
213{
214 struct commit_graph *g = xcalloc(1, sizeof(*g));
215
216 return g;
217}
218
219static int commit_graph_compatible(struct repository *r)
220{
221 if (!r->gitdir)
222 return 0;
223
224 if (replace_refs_enabled(r)) {
225 prepare_replace_object(r);
226 if (oidmap_get_size(&r->objects->replace_map))
227 return 0;
228 }
229
230 prepare_commit_graft(r);
231 if (r->parsed_objects &&
232 (r->parsed_objects->grafts_nr || r->parsed_objects->substituted_parent))
233 return 0;
234 if (is_repository_shallow(r))
235 return 0;
236
237 return 1;
238}
239
240int open_commit_graph(const char *graph_file, int *fd, struct stat *st)
241{
242 *fd = git_open(graph_file);
243 if (*fd < 0)
244 return 0;
245 if (fstat(*fd, st)) {
246 close(*fd);
247 return 0;
248 }
249 return 1;
250}
251
252struct commit_graph *load_commit_graph_one_fd_st(struct repository *r,
253 int fd, struct stat *st,
254 struct odb_source *source)
255{
256 void *graph_map;
257 size_t graph_size;
258 struct commit_graph *ret;
259
260 graph_size = xsize_t(st->st_size);
261
262 if (graph_size < GRAPH_MIN_SIZE) {
263 close(fd);
264 error(_("commit-graph file is too small"));
265 return NULL;
266 }
267 graph_map = xmmap(NULL, graph_size, PROT_READ, MAP_PRIVATE, fd, 0);
268 close(fd);
269 prepare_repo_settings(r);
270 ret = parse_commit_graph(&r->settings, graph_map, graph_size);
271
272 if (ret)
273 ret->odb_source = source;
274 else
275 munmap(graph_map, graph_size);
276
277 return ret;
278}
279
280static int graph_read_oid_fanout(const unsigned char *chunk_start,
281 size_t chunk_size, void *data)
282{
283 struct commit_graph *g = data;
284 int i;
285
286 if (chunk_size != 256 * sizeof(uint32_t))
287 return error(_("commit-graph oid fanout chunk is wrong size"));
288 g->chunk_oid_fanout = (const uint32_t *)chunk_start;
289 g->num_commits = ntohl(g->chunk_oid_fanout[255]);
290
291 for (i = 0; i < 255; i++) {
292 uint32_t oid_fanout1 = ntohl(g->chunk_oid_fanout[i]);
293 uint32_t oid_fanout2 = ntohl(g->chunk_oid_fanout[i + 1]);
294
295 if (oid_fanout1 > oid_fanout2) {
296 error(_("commit-graph fanout values out of order"));
297 return 1;
298 }
299 }
300
301 return 0;
302}
303
304static int graph_read_oid_lookup(const unsigned char *chunk_start,
305 size_t chunk_size, void *data)
306{
307 struct commit_graph *g = data;
308 g->chunk_oid_lookup = chunk_start;
309 if (chunk_size / g->hash_len != g->num_commits)
310 return error(_("commit-graph OID lookup chunk is the wrong size"));
311 return 0;
312}
313
314static int graph_read_commit_data(const unsigned char *chunk_start,
315 size_t chunk_size, void *data)
316{
317 struct commit_graph *g = data;
318 if (chunk_size / GRAPH_DATA_WIDTH != g->num_commits)
319 return error(_("commit-graph commit data chunk is wrong size"));
320 g->chunk_commit_data = chunk_start;
321 return 0;
322}
323
324static int graph_read_generation_data(const unsigned char *chunk_start,
325 size_t chunk_size, void *data)
326{
327 struct commit_graph *g = data;
328 if (chunk_size / sizeof(uint32_t) != g->num_commits)
329 return error(_("commit-graph generations chunk is wrong size"));
330 g->chunk_generation_data = chunk_start;
331 return 0;
332}
333
334static int graph_read_bloom_index(const unsigned char *chunk_start,
335 size_t chunk_size, void *data)
336{
337 struct commit_graph *g = data;
338 if (chunk_size / 4 != g->num_commits) {
339 warning(_("commit-graph changed-path index chunk is too small"));
340 return -1;
341 }
342 g->chunk_bloom_indexes = chunk_start;
343 return 0;
344}
345
346static int graph_read_bloom_data(const unsigned char *chunk_start,
347 size_t chunk_size, void *data)
348{
349 struct commit_graph *g = data;
350
351 if (chunk_size < BLOOMDATA_CHUNK_HEADER_SIZE) {
352 warning(_("ignoring too-small changed-path chunk"
353 " (%"PRIuMAX" < %"PRIuMAX") in commit-graph file"),
354 (uintmax_t)chunk_size,
355 (uintmax_t)BLOOMDATA_CHUNK_HEADER_SIZE);
356 return -1;
357 }
358
359 g->chunk_bloom_data = chunk_start;
360 g->chunk_bloom_data_size = chunk_size;
361
362 g->bloom_filter_settings = xmalloc(sizeof(struct bloom_filter_settings));
363 g->bloom_filter_settings->hash_version = get_be32(chunk_start);
364 g->bloom_filter_settings->num_hashes = get_be32(chunk_start + 4);
365 g->bloom_filter_settings->bits_per_entry = get_be32(chunk_start + 8);
366 g->bloom_filter_settings->max_changed_paths = DEFAULT_BLOOM_MAX_CHANGES;
367
368 return 0;
369}
370
371struct commit_graph *parse_commit_graph(struct repo_settings *s,
372 void *graph_map, size_t graph_size)
373{
374 const unsigned char *data;
375 struct commit_graph *graph;
376 uint32_t graph_signature;
377 unsigned char graph_version, hash_version;
378 struct chunkfile *cf = NULL;
379
380 if (!graph_map)
381 return NULL;
382
383 if (graph_size < GRAPH_MIN_SIZE)
384 return NULL;
385
386 data = (const unsigned char *)graph_map;
387
388 graph_signature = get_be32(data);
389 if (graph_signature != GRAPH_SIGNATURE) {
390 error(_("commit-graph signature %X does not match signature %X"),
391 graph_signature, GRAPH_SIGNATURE);
392 return NULL;
393 }
394
395 graph_version = *(unsigned char*)(data + 4);
396 if (graph_version != GRAPH_VERSION) {
397 error(_("commit-graph version %X does not match version %X"),
398 graph_version, GRAPH_VERSION);
399 return NULL;
400 }
401
402 hash_version = *(unsigned char*)(data + 5);
403 if (hash_version != oid_version(the_hash_algo)) {
404 error(_("commit-graph hash version %X does not match version %X"),
405 hash_version, oid_version(the_hash_algo));
406 return NULL;
407 }
408
409 graph = alloc_commit_graph();
410
411 graph->hash_len = the_hash_algo->rawsz;
412 graph->num_chunks = *(unsigned char*)(data + 6);
413 graph->data = graph_map;
414 graph->data_len = graph_size;
415
416 if (graph_size < GRAPH_HEADER_SIZE +
417 (graph->num_chunks + 1) * CHUNK_TOC_ENTRY_SIZE +
418 GRAPH_FANOUT_SIZE + the_hash_algo->rawsz) {
419 error(_("commit-graph file is too small to hold %u chunks"),
420 graph->num_chunks);
421 free(graph);
422 return NULL;
423 }
424
425 cf = init_chunkfile(NULL);
426
427 if (read_table_of_contents(cf, graph->data, graph_size,
428 GRAPH_HEADER_SIZE, graph->num_chunks, 1))
429 goto free_and_return;
430
431 if (read_chunk(cf, GRAPH_CHUNKID_OIDFANOUT, graph_read_oid_fanout, graph)) {
432 error(_("commit-graph required OID fanout chunk missing or corrupted"));
433 goto free_and_return;
434 }
435 if (read_chunk(cf, GRAPH_CHUNKID_OIDLOOKUP, graph_read_oid_lookup, graph)) {
436 error(_("commit-graph required OID lookup chunk missing or corrupted"));
437 goto free_and_return;
438 }
439 if (read_chunk(cf, GRAPH_CHUNKID_DATA, graph_read_commit_data, graph)) {
440 error(_("commit-graph required commit data chunk missing or corrupted"));
441 goto free_and_return;
442 }
443
444 pair_chunk(cf, GRAPH_CHUNKID_EXTRAEDGES, &graph->chunk_extra_edges,
445 &graph->chunk_extra_edges_size);
446 pair_chunk(cf, GRAPH_CHUNKID_BASE, &graph->chunk_base_graphs,
447 &graph->chunk_base_graphs_size);
448
449 if (s->commit_graph_generation_version >= 2) {
450 read_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA,
451 graph_read_generation_data, graph);
452 pair_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW,
453 &graph->chunk_generation_data_overflow,
454 &graph->chunk_generation_data_overflow_size);
455
456 if (graph->chunk_generation_data)
457 graph->read_generation_data = 1;
458 }
459
460 if (s->commit_graph_changed_paths_version) {
461 read_chunk(cf, GRAPH_CHUNKID_BLOOMINDEXES,
462 graph_read_bloom_index, graph);
463 read_chunk(cf, GRAPH_CHUNKID_BLOOMDATA,
464 graph_read_bloom_data, graph);
465 }
466
467 if (graph->chunk_bloom_indexes && graph->chunk_bloom_data) {
468 init_bloom_filters();
469 } else {
470 /* We need both the bloom chunks to exist together. Else ignore the data */
471 graph->chunk_bloom_indexes = NULL;
472 graph->chunk_bloom_data = NULL;
473 FREE_AND_NULL(graph->bloom_filter_settings);
474 }
475
476 oidread(&graph->oid, graph->data + graph->data_len - graph->hash_len,
477 the_repository->hash_algo);
478
479 free_chunkfile(cf);
480 return graph;
481
482free_and_return:
483 free_chunkfile(cf);
484 free(graph->bloom_filter_settings);
485 free(graph);
486 return NULL;
487}
488
489static struct commit_graph *load_commit_graph_one(struct repository *r,
490 const char *graph_file,
491 struct odb_source *source)
492{
493
494 struct stat st;
495 int fd;
496 struct commit_graph *g;
497 int open_ok = open_commit_graph(graph_file, &fd, &st);
498
499 if (!open_ok)
500 return NULL;
501
502 g = load_commit_graph_one_fd_st(r, fd, &st, source);
503
504 if (g)
505 g->filename = xstrdup(graph_file);
506
507 return g;
508}
509
510static struct commit_graph *load_commit_graph_v1(struct repository *r,
511 struct odb_source *source)
512{
513 char *graph_name = get_commit_graph_filename(source);
514 struct commit_graph *g = load_commit_graph_one(r, graph_name, source);
515 free(graph_name);
516
517 return g;
518}
519
520/*
521 * returns 1 if and only if all graphs in the chain have
522 * corrected commit dates stored in the generation_data chunk.
523 */
524static int validate_mixed_generation_chain(struct commit_graph *g)
525{
526 int read_generation_data = 1;
527 struct commit_graph *p = g;
528
529 while (read_generation_data && p) {
530 read_generation_data = p->read_generation_data;
531 p = p->base_graph;
532 }
533
534 if (read_generation_data)
535 return 1;
536
537 while (g) {
538 g->read_generation_data = 0;
539 g = g->base_graph;
540 }
541
542 return 0;
543}
544
545static void validate_mixed_bloom_settings(struct commit_graph *g)
546{
547 struct bloom_filter_settings *settings = NULL;
548 for (; g; g = g->base_graph) {
549 if (!g->bloom_filter_settings)
550 continue;
551 if (!settings) {
552 settings = g->bloom_filter_settings;
553 continue;
554 }
555
556 if (g->bloom_filter_settings->bits_per_entry != settings->bits_per_entry ||
557 g->bloom_filter_settings->num_hashes != settings->num_hashes ||
558 g->bloom_filter_settings->hash_version != settings->hash_version) {
559 g->chunk_bloom_indexes = NULL;
560 g->chunk_bloom_data = NULL;
561 FREE_AND_NULL(g->bloom_filter_settings);
562
563 warning(_("disabling Bloom filters for commit-graph "
564 "layer '%s' due to incompatible settings"),
565 oid_to_hex(&g->oid));
566 }
567 }
568}
569
570static int add_graph_to_chain(struct commit_graph *g,
571 struct commit_graph *chain,
572 struct object_id *oids,
573 int n)
574{
575 struct commit_graph *cur_g = chain;
576
577 if (n && !g->chunk_base_graphs) {
578 warning(_("commit-graph has no base graphs chunk"));
579 return 0;
580 }
581
582 if (g->chunk_base_graphs_size / g->hash_len < n) {
583 warning(_("commit-graph base graphs chunk is too small"));
584 return 0;
585 }
586
587 while (n) {
588 n--;
589
590 if (!cur_g ||
591 !oideq(&oids[n], &cur_g->oid) ||
592 !hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_len, n),
593 the_repository->hash_algo)) {
594 warning(_("commit-graph chain does not match"));
595 return 0;
596 }
597
598 cur_g = cur_g->base_graph;
599 }
600
601 if (chain) {
602 if (unsigned_add_overflows(chain->num_commits,
603 chain->num_commits_in_base)) {
604 warning(_("commit count in base graph too high: %"PRIuMAX),
605 (uintmax_t)chain->num_commits_in_base);
606 return 0;
607 }
608 g->num_commits_in_base = chain->num_commits + chain->num_commits_in_base;
609 }
610
611 g->base_graph = chain;
612
613 return 1;
614}
615
616int open_commit_graph_chain(const char *chain_file,
617 int *fd, struct stat *st)
618{
619 *fd = git_open(chain_file);
620 if (*fd < 0)
621 return 0;
622 if (fstat(*fd, st)) {
623 close(*fd);
624 return 0;
625 }
626 if (st->st_size < the_hash_algo->hexsz) {
627 close(*fd);
628 if (!st->st_size) {
629 /* treat empty files the same as missing */
630 errno = ENOENT;
631 } else {
632 warning(_("commit-graph chain file too small"));
633 errno = EINVAL;
634 }
635 return 0;
636 }
637 return 1;
638}
639
640struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,
641 int fd, struct stat *st,
642 int *incomplete_chain)
643{
644 struct commit_graph *graph_chain = NULL;
645 struct strbuf line = STRBUF_INIT;
646 struct object_id *oids;
647 int i = 0, valid = 1, count;
648 FILE *fp = xfdopen(fd, "r");
649
650 count = st->st_size / (the_hash_algo->hexsz + 1);
651 CALLOC_ARRAY(oids, count);
652
653 odb_prepare_alternates(r->objects);
654
655 for (i = 0; i < count; i++) {
656 struct odb_source *source;
657
658 if (strbuf_getline_lf(&line, fp) == EOF)
659 break;
660
661 if (get_oid_hex(line.buf, &oids[i])) {
662 warning(_("invalid commit-graph chain: line '%s' not a hash"),
663 line.buf);
664 valid = 0;
665 break;
666 }
667
668 valid = 0;
669 for (source = r->objects->sources; source; source = source->next) {
670 char *graph_name = get_split_graph_filename(source, line.buf);
671 struct commit_graph *g = load_commit_graph_one(r, graph_name, source);
672
673 free(graph_name);
674
675 if (g) {
676 if (add_graph_to_chain(g, graph_chain, oids, i)) {
677 graph_chain = g;
678 valid = 1;
679 } else {
680 free_commit_graph(g);
681 }
682
683 break;
684 }
685 }
686
687 if (!valid) {
688 warning(_("unable to find all commit-graph files"));
689 break;
690 }
691 }
692
693 validate_mixed_generation_chain(graph_chain);
694 validate_mixed_bloom_settings(graph_chain);
695
696 free(oids);
697 fclose(fp);
698 strbuf_release(&line);
699
700 *incomplete_chain = !valid;
701 return graph_chain;
702}
703
704static struct commit_graph *load_commit_graph_chain(struct repository *r,
705 struct odb_source *source)
706{
707 char *chain_file = get_commit_graph_chain_filename(source);
708 struct stat st;
709 int fd;
710 struct commit_graph *g = NULL;
711
712 if (open_commit_graph_chain(chain_file, &fd, &st)) {
713 int incomplete;
714 /* ownership of fd is taken over by load function */
715 g = load_commit_graph_chain_fd_st(r, fd, &st, &incomplete);
716 }
717
718 free(chain_file);
719 return g;
720}
721
722struct commit_graph *read_commit_graph_one(struct repository *r,
723 struct odb_source *source)
724{
725 struct commit_graph *g = load_commit_graph_v1(r, source);
726
727 if (!g)
728 g = load_commit_graph_chain(r, source);
729
730 return g;
731}
732
733static void prepare_commit_graph_one(struct repository *r,
734 struct odb_source *source)
735{
736
737 if (r->objects->commit_graph)
738 return;
739
740 r->objects->commit_graph = read_commit_graph_one(r, source);
741}
742
743/*
744 * Return 1 if commit_graph is non-NULL, and 0 otherwise.
745 *
746 * On the first invocation, this function attempts to load the commit
747 * graph if the_repository is configured to have one.
748 */
749static int prepare_commit_graph(struct repository *r)
750{
751 struct odb_source *source;
752
753 /*
754 * Early return if there is no git dir or if the commit graph is
755 * disabled.
756 *
757 * This must come before the "already attempted?" check below, because
758 * we want to disable even an already-loaded graph file.
759 */
760 if (!r->gitdir || r->commit_graph_disabled)
761 return 0;
762
763 if (r->objects->commit_graph_attempted)
764 return !!r->objects->commit_graph;
765 r->objects->commit_graph_attempted = 1;
766
767 prepare_repo_settings(r);
768
769 if (!git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) &&
770 r->settings.core_commit_graph != 1)
771 /*
772 * This repository is not configured to use commit graphs, so
773 * do not load one. (But report commit_graph_attempted anyway
774 * so that commit graph loading is not attempted again for this
775 * repository.)
776 */
777 return 0;
778
779 if (!commit_graph_compatible(r))
780 return 0;
781
782 odb_prepare_alternates(r->objects);
783 for (source = r->objects->sources;
784 !r->objects->commit_graph && source;
785 source = source->next)
786 prepare_commit_graph_one(r, source);
787 return !!r->objects->commit_graph;
788}
789
790int generation_numbers_enabled(struct repository *r)
791{
792 uint32_t first_generation;
793 struct commit_graph *g;
794 if (!prepare_commit_graph(r))
795 return 0;
796
797 g = r->objects->commit_graph;
798
799 if (!g->num_commits)
800 return 0;
801
802 first_generation = get_be32(g->chunk_commit_data +
803 g->hash_len + 8) >> 2;
804
805 return !!first_generation;
806}
807
808int corrected_commit_dates_enabled(struct repository *r)
809{
810 struct commit_graph *g;
811 if (!prepare_commit_graph(r))
812 return 0;
813
814 g = r->objects->commit_graph;
815
816 if (!g->num_commits)
817 return 0;
818
819 return g->read_generation_data;
820}
821
822struct bloom_filter_settings *get_bloom_filter_settings(struct repository *r)
823{
824 struct commit_graph *g = r->objects->commit_graph;
825 while (g) {
826 if (g->bloom_filter_settings)
827 return g->bloom_filter_settings;
828 g = g->base_graph;
829 }
830 return NULL;
831}
832
833void close_commit_graph(struct object_database *o)
834{
835 if (!o->commit_graph)
836 return;
837
838 clear_commit_graph_data_slab(&commit_graph_data_slab);
839 deinit_bloom_filters();
840 free_commit_graph(o->commit_graph);
841 o->commit_graph = NULL;
842}
843
844static int bsearch_graph(struct commit_graph *g, const struct object_id *oid, uint32_t *pos)
845{
846 return bsearch_hash(oid->hash, g->chunk_oid_fanout,
847 g->chunk_oid_lookup, g->hash_len, pos);
848}
849
850static void load_oid_from_graph(struct commit_graph *g,
851 uint32_t pos,
852 struct object_id *oid)
853{
854 uint32_t lex_index;
855
856 while (g && pos < g->num_commits_in_base)
857 g = g->base_graph;
858
859 if (!g)
860 BUG("NULL commit-graph");
861
862 if (pos >= g->num_commits + g->num_commits_in_base)
863 die(_("invalid commit position. commit-graph is likely corrupt"));
864
865 lex_index = pos - g->num_commits_in_base;
866
867 oidread(oid, g->chunk_oid_lookup + st_mult(g->hash_len, lex_index),
868 the_repository->hash_algo);
869}
870
871static struct commit_list **insert_parent_or_die(struct repository *r,
872 struct commit_graph *g,
873 uint32_t pos,
874 struct commit_list **pptr)
875{
876 struct commit *c;
877 struct object_id oid;
878
879 if (pos >= g->num_commits + g->num_commits_in_base)
880 die("invalid parent position %"PRIu32, pos);
881
882 load_oid_from_graph(g, pos, &oid);
883 c = lookup_commit(r, &oid);
884 if (!c)
885 die(_("could not find commit %s"), oid_to_hex(&oid));
886 commit_graph_data_at(c)->graph_pos = pos;
887 return &commit_list_insert(c, pptr)->next;
888}
889
890static void fill_commit_graph_info(struct commit *item, struct commit_graph *g, uint32_t pos)
891{
892 const unsigned char *commit_data;
893 struct commit_graph_data *graph_data;
894 uint32_t lex_index, offset_pos;
895 uint64_t date_high, date_low, offset;
896
897 while (pos < g->num_commits_in_base)
898 g = g->base_graph;
899
900 if (pos >= g->num_commits + g->num_commits_in_base)
901 die(_("invalid commit position. commit-graph is likely corrupt"));
902
903 lex_index = pos - g->num_commits_in_base;
904 commit_data = g->chunk_commit_data + st_mult(GRAPH_DATA_WIDTH, lex_index);
905
906 graph_data = commit_graph_data_at(item);
907 graph_data->graph_pos = pos;
908
909 date_high = get_be32(commit_data + g->hash_len + 8) & 0x3;
910 date_low = get_be32(commit_data + g->hash_len + 12);
911 item->date = (timestamp_t)((date_high << 32) | date_low);
912
913 if (g->read_generation_data) {
914 offset = (timestamp_t)get_be32(g->chunk_generation_data + st_mult(sizeof(uint32_t), lex_index));
915
916 if (offset & CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW) {
917 if (!g->chunk_generation_data_overflow)
918 die(_("commit-graph requires overflow generation data but has none"));
919
920 offset_pos = offset ^ CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW;
921 if (g->chunk_generation_data_overflow_size / sizeof(uint64_t) <= offset_pos)
922 die(_("commit-graph overflow generation data is too small"));
923 graph_data->generation = item->date +
924 get_be64(g->chunk_generation_data_overflow + sizeof(uint64_t) * offset_pos);
925 } else
926 graph_data->generation = item->date + offset;
927 } else
928 graph_data->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
929
930 if (g->topo_levels)
931 *topo_level_slab_at(g->topo_levels, item) = get_be32(commit_data + g->hash_len + 8) >> 2;
932}
933
934static inline void set_commit_tree(struct commit *c, struct tree *t)
935{
936 c->maybe_tree = t;
937}
938
939static int fill_commit_in_graph(struct repository *r,
940 struct commit *item,
941 struct commit_graph *g, uint32_t pos)
942{
943 uint32_t edge_value;
944 uint32_t parent_data_pos;
945 struct commit_list **pptr;
946 const unsigned char *commit_data;
947 uint32_t lex_index;
948
949 while (pos < g->num_commits_in_base)
950 g = g->base_graph;
951
952 fill_commit_graph_info(item, g, pos);
953
954 lex_index = pos - g->num_commits_in_base;
955 commit_data = g->chunk_commit_data + st_mult(g->hash_len + 16, lex_index);
956
957 item->object.parsed = 1;
958
959 set_commit_tree(item, NULL);
960
961 pptr = &item->parents;
962
963 edge_value = get_be32(commit_data + g->hash_len);
964 if (edge_value == GRAPH_PARENT_NONE)
965 return 1;
966 pptr = insert_parent_or_die(r, g, edge_value, pptr);
967
968 edge_value = get_be32(commit_data + g->hash_len + 4);
969 if (edge_value == GRAPH_PARENT_NONE)
970 return 1;
971 if (!(edge_value & GRAPH_EXTRA_EDGES_NEEDED)) {
972 pptr = insert_parent_or_die(r, g, edge_value, pptr);
973 return 1;
974 }
975
976 parent_data_pos = edge_value & GRAPH_EDGE_LAST_MASK;
977 do {
978 if (g->chunk_extra_edges_size / sizeof(uint32_t) <= parent_data_pos) {
979 error(_("commit-graph extra-edges pointer out of bounds"));
980 free_commit_list(item->parents);
981 item->parents = NULL;
982 item->object.parsed = 0;
983 return 0;
984 }
985 edge_value = get_be32(g->chunk_extra_edges +
986 sizeof(uint32_t) * parent_data_pos);
987 pptr = insert_parent_or_die(r, g,
988 edge_value & GRAPH_EDGE_LAST_MASK,
989 pptr);
990 parent_data_pos++;
991 } while (!(edge_value & GRAPH_LAST_EDGE));
992
993 return 1;
994}
995
996static int search_commit_pos_in_graph(const struct object_id *id, struct commit_graph *g, uint32_t *pos)
997{
998 struct commit_graph *cur_g = g;
999 uint32_t lex_index;
1000
1001 while (cur_g && !bsearch_graph(cur_g, id, &lex_index))
1002 cur_g = cur_g->base_graph;
1003
1004 if (cur_g) {
1005 *pos = lex_index + cur_g->num_commits_in_base;
1006 return 1;
1007 }
1008
1009 return 0;
1010}
1011
1012static int find_commit_pos_in_graph(struct commit *item, struct commit_graph *g, uint32_t *pos)
1013{
1014 uint32_t graph_pos = commit_graph_position(item);
1015 if (graph_pos != COMMIT_NOT_FROM_GRAPH) {
1016 *pos = graph_pos;
1017 return 1;
1018 } else {
1019 return search_commit_pos_in_graph(&item->object.oid, g, pos);
1020 }
1021}
1022
1023int repo_find_commit_pos_in_graph(struct repository *r, struct commit *c,
1024 uint32_t *pos)
1025{
1026 if (!prepare_commit_graph(r))
1027 return 0;
1028 return find_commit_pos_in_graph(c, r->objects->commit_graph, pos);
1029}
1030
1031struct commit *lookup_commit_in_graph(struct repository *repo, const struct object_id *id)
1032{
1033 static int commit_graph_paranoia = -1;
1034 struct commit *commit;
1035 uint32_t pos;
1036
1037 if (commit_graph_paranoia == -1)
1038 commit_graph_paranoia = git_env_bool(GIT_COMMIT_GRAPH_PARANOIA, 0);
1039
1040 if (!prepare_commit_graph(repo))
1041 return NULL;
1042 if (!search_commit_pos_in_graph(id, repo->objects->commit_graph, &pos))
1043 return NULL;
1044 if (commit_graph_paranoia && !odb_has_object(repo->objects, id, 0))
1045 return NULL;
1046
1047 commit = lookup_commit(repo, id);
1048 if (!commit)
1049 return NULL;
1050 if (commit->object.parsed)
1051 return commit;
1052
1053 if (!fill_commit_in_graph(repo, commit, repo->objects->commit_graph, pos))
1054 return NULL;
1055
1056 return commit;
1057}
1058
1059static int parse_commit_in_graph_one(struct repository *r,
1060 struct commit_graph *g,
1061 struct commit *item)
1062{
1063 uint32_t pos;
1064
1065 if (item->object.parsed)
1066 return 1;
1067
1068 if (find_commit_pos_in_graph(item, g, &pos))
1069 return fill_commit_in_graph(r, item, g, pos);
1070
1071 return 0;
1072}
1073
1074int parse_commit_in_graph(struct repository *r, struct commit *item)
1075{
1076 static int checked_env = 0;
1077
1078 if (!checked_env &&
1079 git_env_bool(GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE, 0))
1080 die("dying as requested by the '%s' variable on commit-graph parse!",
1081 GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE);
1082 checked_env = 1;
1083
1084 if (!prepare_commit_graph(r))
1085 return 0;
1086 return parse_commit_in_graph_one(r, r->objects->commit_graph, item);
1087}
1088
1089void load_commit_graph_info(struct repository *r, struct commit *item)
1090{
1091 uint32_t pos;
1092 if (repo_find_commit_pos_in_graph(r, item, &pos))
1093 fill_commit_graph_info(item, r->objects->commit_graph, pos);
1094}
1095
1096static struct tree *load_tree_for_commit(struct repository *r,
1097 struct commit_graph *g,
1098 struct commit *c)
1099{
1100 struct object_id oid;
1101 const unsigned char *commit_data;
1102 uint32_t graph_pos = commit_graph_position(c);
1103
1104 while (graph_pos < g->num_commits_in_base)
1105 g = g->base_graph;
1106
1107 commit_data = g->chunk_commit_data +
1108 st_mult(GRAPH_DATA_WIDTH, graph_pos - g->num_commits_in_base);
1109
1110 oidread(&oid, commit_data, the_repository->hash_algo);
1111 set_commit_tree(c, lookup_tree(r, &oid));
1112
1113 return c->maybe_tree;
1114}
1115
1116static struct tree *get_commit_tree_in_graph_one(struct repository *r,
1117 struct commit_graph *g,
1118 const struct commit *c)
1119{
1120 if (c->maybe_tree)
1121 return c->maybe_tree;
1122 if (commit_graph_position(c) == COMMIT_NOT_FROM_GRAPH)
1123 BUG("get_commit_tree_in_graph_one called from non-commit-graph commit");
1124
1125 return load_tree_for_commit(r, g, (struct commit *)c);
1126}
1127
1128struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit *c)
1129{
1130 return get_commit_tree_in_graph_one(r, r->objects->commit_graph, c);
1131}
1132
1133struct packed_commit_list {
1134 struct commit **list;
1135 size_t nr;
1136 size_t alloc;
1137};
1138
1139struct write_commit_graph_context {
1140 struct repository *r;
1141 struct odb_source *odb_source;
1142 char *graph_name;
1143 struct oid_array oids;
1144 struct packed_commit_list commits;
1145 int num_extra_edges;
1146 int num_generation_data_overflows;
1147 unsigned long approx_nr_objects;
1148 struct progress *progress;
1149 int progress_done;
1150 uint64_t progress_cnt;
1151
1152 char *base_graph_name;
1153 int num_commit_graphs_before;
1154 int num_commit_graphs_after;
1155 char **commit_graph_filenames_before;
1156 char **commit_graph_filenames_after;
1157 char **commit_graph_hash_after;
1158 uint32_t new_num_commits_in_base;
1159 struct commit_graph *new_base_graph;
1160
1161 unsigned append:1,
1162 report_progress:1,
1163 split:1,
1164 changed_paths:1,
1165 order_by_pack:1,
1166 write_generation_data:1,
1167 trust_generation_numbers:1;
1168
1169 struct topo_level_slab *topo_levels;
1170 const struct commit_graph_opts *opts;
1171 size_t total_bloom_filter_data_size;
1172 const struct bloom_filter_settings *bloom_settings;
1173
1174 int count_bloom_filter_computed;
1175 int count_bloom_filter_not_computed;
1176 int count_bloom_filter_trunc_empty;
1177 int count_bloom_filter_trunc_large;
1178 int count_bloom_filter_upgraded;
1179};
1180
1181static int write_graph_chunk_fanout(struct hashfile *f,
1182 void *data)
1183{
1184 struct write_commit_graph_context *ctx = data;
1185 int i, count = 0;
1186 struct commit **list = ctx->commits.list;
1187
1188 /*
1189 * Write the first-level table (the list is sorted,
1190 * but we use a 256-entry lookup to be able to avoid
1191 * having to do eight extra binary search iterations).
1192 */
1193 for (i = 0; i < 256; i++) {
1194 while (count < ctx->commits.nr) {
1195 if ((*list)->object.oid.hash[0] != i)
1196 break;
1197 display_progress(ctx->progress, ++ctx->progress_cnt);
1198 count++;
1199 list++;
1200 }
1201
1202 hashwrite_be32(f, count);
1203 }
1204
1205 return 0;
1206}
1207
1208static int write_graph_chunk_oids(struct hashfile *f,
1209 void *data)
1210{
1211 struct write_commit_graph_context *ctx = data;
1212 struct commit **list = ctx->commits.list;
1213 int count;
1214 for (count = 0; count < ctx->commits.nr; count++, list++) {
1215 display_progress(ctx->progress, ++ctx->progress_cnt);
1216 hashwrite(f, (*list)->object.oid.hash, the_hash_algo->rawsz);
1217 }
1218
1219 return 0;
1220}
1221
1222static const struct object_id *commit_to_oid(size_t index, const void *table)
1223{
1224 const struct commit * const *commits = table;
1225 return &commits[index]->object.oid;
1226}
1227
1228static int write_graph_chunk_data(struct hashfile *f,
1229 void *data)
1230{
1231 struct write_commit_graph_context *ctx = data;
1232 struct commit **list = ctx->commits.list;
1233 struct commit **last = ctx->commits.list + ctx->commits.nr;
1234 uint32_t num_extra_edges = 0;
1235
1236 while (list < last) {
1237 struct commit_list *parent;
1238 struct object_id *tree;
1239 int edge_value;
1240 uint32_t packedDate[2];
1241 display_progress(ctx->progress, ++ctx->progress_cnt);
1242
1243 if (repo_parse_commit_no_graph(ctx->r, *list))
1244 die(_("unable to parse commit %s"),
1245 oid_to_hex(&(*list)->object.oid));
1246 tree = get_commit_tree_oid(*list);
1247 hashwrite(f, tree->hash, the_hash_algo->rawsz);
1248
1249 parent = (*list)->parents;
1250
1251 if (!parent)
1252 edge_value = GRAPH_PARENT_NONE;
1253 else {
1254 edge_value = oid_pos(&parent->item->object.oid,
1255 ctx->commits.list,
1256 ctx->commits.nr,
1257 commit_to_oid);
1258
1259 if (edge_value >= 0)
1260 edge_value += ctx->new_num_commits_in_base;
1261 else if (ctx->new_base_graph) {
1262 uint32_t pos;
1263 if (find_commit_pos_in_graph(parent->item,
1264 ctx->new_base_graph,
1265 &pos))
1266 edge_value = pos;
1267 }
1268
1269 if (edge_value < 0)
1270 BUG("missing parent %s for commit %s",
1271 oid_to_hex(&parent->item->object.oid),
1272 oid_to_hex(&(*list)->object.oid));
1273 }
1274
1275 hashwrite_be32(f, edge_value);
1276
1277 if (parent)
1278 parent = parent->next;
1279
1280 if (!parent)
1281 edge_value = GRAPH_PARENT_NONE;
1282 else if (parent->next)
1283 edge_value = GRAPH_EXTRA_EDGES_NEEDED | num_extra_edges;
1284 else {
1285 edge_value = oid_pos(&parent->item->object.oid,
1286 ctx->commits.list,
1287 ctx->commits.nr,
1288 commit_to_oid);
1289
1290 if (edge_value >= 0)
1291 edge_value += ctx->new_num_commits_in_base;
1292 else if (ctx->new_base_graph) {
1293 uint32_t pos;
1294 if (find_commit_pos_in_graph(parent->item,
1295 ctx->new_base_graph,
1296 &pos))
1297 edge_value = pos;
1298 }
1299
1300 if (edge_value < 0)
1301 BUG("missing parent %s for commit %s",
1302 oid_to_hex(&parent->item->object.oid),
1303 oid_to_hex(&(*list)->object.oid));
1304 }
1305
1306 hashwrite_be32(f, edge_value);
1307
1308 if (edge_value & GRAPH_EXTRA_EDGES_NEEDED) {
1309 do {
1310 num_extra_edges++;
1311 parent = parent->next;
1312 } while (parent);
1313 }
1314
1315 if (sizeof((*list)->date) > 4)
1316 packedDate[0] = htonl(((*list)->date >> 32) & 0x3);
1317 else
1318 packedDate[0] = 0;
1319
1320 packedDate[0] |= htonl(*topo_level_slab_at(ctx->topo_levels, *list) << 2);
1321
1322 packedDate[1] = htonl((*list)->date);
1323 hashwrite(f, packedDate, 8);
1324
1325 list++;
1326 }
1327
1328 return 0;
1329}
1330
1331static int write_graph_chunk_generation_data(struct hashfile *f,
1332 void *data)
1333{
1334 struct write_commit_graph_context *ctx = data;
1335 int i, num_generation_data_overflows = 0;
1336
1337 for (i = 0; i < ctx->commits.nr; i++) {
1338 struct commit *c = ctx->commits.list[i];
1339 timestamp_t offset;
1340 repo_parse_commit(ctx->r, c);
1341 offset = commit_graph_data_at(c)->generation - c->date;
1342 display_progress(ctx->progress, ++ctx->progress_cnt);
1343
1344 if (offset > GENERATION_NUMBER_V2_OFFSET_MAX) {
1345 offset = CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW | num_generation_data_overflows;
1346 num_generation_data_overflows++;
1347 }
1348
1349 hashwrite_be32(f, offset);
1350 }
1351
1352 return 0;
1353}
1354
1355static int write_graph_chunk_generation_data_overflow(struct hashfile *f,
1356 void *data)
1357{
1358 struct write_commit_graph_context *ctx = data;
1359 int i;
1360 for (i = 0; i < ctx->commits.nr; i++) {
1361 struct commit *c = ctx->commits.list[i];
1362 timestamp_t offset = commit_graph_data_at(c)->generation - c->date;
1363 display_progress(ctx->progress, ++ctx->progress_cnt);
1364
1365 if (offset > GENERATION_NUMBER_V2_OFFSET_MAX) {
1366 hashwrite_be32(f, offset >> 32);
1367 hashwrite_be32(f, (uint32_t) offset);
1368 }
1369 }
1370
1371 return 0;
1372}
1373
1374static int write_graph_chunk_extra_edges(struct hashfile *f,
1375 void *data)
1376{
1377 struct write_commit_graph_context *ctx = data;
1378 struct commit **list = ctx->commits.list;
1379 struct commit **last = ctx->commits.list + ctx->commits.nr;
1380 struct commit_list *parent;
1381
1382 while (list < last) {
1383 int num_parents = 0;
1384
1385 display_progress(ctx->progress, ++ctx->progress_cnt);
1386
1387 for (parent = (*list)->parents; num_parents < 3 && parent;
1388 parent = parent->next)
1389 num_parents++;
1390
1391 if (num_parents <= 2) {
1392 list++;
1393 continue;
1394 }
1395
1396 /* Since num_parents > 2, this initializer is safe. */
1397 for (parent = (*list)->parents->next; parent; parent = parent->next) {
1398 int edge_value = oid_pos(&parent->item->object.oid,
1399 ctx->commits.list,
1400 ctx->commits.nr,
1401 commit_to_oid);
1402
1403 if (edge_value >= 0)
1404 edge_value += ctx->new_num_commits_in_base;
1405 else if (ctx->new_base_graph) {
1406 uint32_t pos;
1407 if (find_commit_pos_in_graph(parent->item,
1408 ctx->new_base_graph,
1409 &pos))
1410 edge_value = pos;
1411 }
1412
1413 if (edge_value < 0)
1414 BUG("missing parent %s for commit %s",
1415 oid_to_hex(&parent->item->object.oid),
1416 oid_to_hex(&(*list)->object.oid));
1417 else if (!parent->next)
1418 edge_value |= GRAPH_LAST_EDGE;
1419
1420 hashwrite_be32(f, edge_value);
1421 }
1422
1423 list++;
1424 }
1425
1426 return 0;
1427}
1428
1429static int write_graph_chunk_bloom_indexes(struct hashfile *f,
1430 void *data)
1431{
1432 struct write_commit_graph_context *ctx = data;
1433 struct commit **list = ctx->commits.list;
1434 struct commit **last = ctx->commits.list + ctx->commits.nr;
1435 uint32_t cur_pos = 0;
1436
1437 while (list < last) {
1438 struct bloom_filter *filter = get_bloom_filter(ctx->r, *list);
1439 size_t len = filter ? filter->len : 0;
1440 cur_pos += len;
1441 display_progress(ctx->progress, ++ctx->progress_cnt);
1442 hashwrite_be32(f, cur_pos);
1443 list++;
1444 }
1445
1446 return 0;
1447}
1448
1449static void trace2_bloom_filter_settings(struct write_commit_graph_context *ctx)
1450{
1451 struct json_writer jw = JSON_WRITER_INIT;
1452
1453 jw_object_begin(&jw, 0);
1454 jw_object_intmax(&jw, "hash_version", ctx->bloom_settings->hash_version);
1455 jw_object_intmax(&jw, "num_hashes", ctx->bloom_settings->num_hashes);
1456 jw_object_intmax(&jw, "bits_per_entry", ctx->bloom_settings->bits_per_entry);
1457 jw_object_intmax(&jw, "max_changed_paths", ctx->bloom_settings->max_changed_paths);
1458 jw_end(&jw);
1459
1460 trace2_data_json("bloom", ctx->r, "settings", &jw);
1461
1462 jw_release(&jw);
1463}
1464
1465static int write_graph_chunk_bloom_data(struct hashfile *f,
1466 void *data)
1467{
1468 struct write_commit_graph_context *ctx = data;
1469 struct commit **list = ctx->commits.list;
1470 struct commit **last = ctx->commits.list + ctx->commits.nr;
1471
1472 trace2_bloom_filter_settings(ctx);
1473
1474 hashwrite_be32(f, ctx->bloom_settings->hash_version);
1475 hashwrite_be32(f, ctx->bloom_settings->num_hashes);
1476 hashwrite_be32(f, ctx->bloom_settings->bits_per_entry);
1477
1478 while (list < last) {
1479 struct bloom_filter *filter = get_bloom_filter(ctx->r, *list);
1480 size_t len = filter ? filter->len : 0;
1481
1482 display_progress(ctx->progress, ++ctx->progress_cnt);
1483 if (len)
1484 hashwrite(f, filter->data, len * sizeof(unsigned char));
1485 list++;
1486 }
1487
1488 return 0;
1489}
1490
1491static int add_packed_commits(const struct object_id *oid,
1492 struct packed_git *pack,
1493 uint32_t pos,
1494 void *data)
1495{
1496 struct write_commit_graph_context *ctx = (struct write_commit_graph_context*)data;
1497 enum object_type type;
1498 off_t offset = nth_packed_object_offset(pack, pos);
1499 struct object_info oi = OBJECT_INFO_INIT;
1500
1501 if (ctx->progress)
1502 display_progress(ctx->progress, ++ctx->progress_done);
1503
1504 oi.typep = &type;
1505 if (packed_object_info(ctx->r, pack, offset, &oi) < 0)
1506 die(_("unable to get type of object %s"), oid_to_hex(oid));
1507
1508 if (type != OBJ_COMMIT)
1509 return 0;
1510
1511 oid_array_append(&ctx->oids, oid);
1512 set_commit_pos(ctx->r, oid);
1513
1514 return 0;
1515}
1516
1517static void add_missing_parents(struct write_commit_graph_context *ctx, struct commit *commit)
1518{
1519 struct commit_list *parent;
1520 for (parent = commit->parents; parent; parent = parent->next) {
1521 if (!(parent->item->object.flags & REACHABLE)) {
1522 oid_array_append(&ctx->oids, &parent->item->object.oid);
1523 parent->item->object.flags |= REACHABLE;
1524 }
1525 }
1526}
1527
1528static void close_reachable(struct write_commit_graph_context *ctx)
1529{
1530 int i;
1531 struct commit *commit;
1532 enum commit_graph_split_flags flags = ctx->opts ?
1533 ctx->opts->split_flags : COMMIT_GRAPH_SPLIT_UNSPECIFIED;
1534
1535 if (ctx->report_progress)
1536 ctx->progress = start_delayed_progress(
1537 the_repository,
1538 _("Loading known commits in commit graph"),
1539 ctx->oids.nr);
1540 for (i = 0; i < ctx->oids.nr; i++) {
1541 display_progress(ctx->progress, i + 1);
1542 commit = lookup_commit(ctx->r, &ctx->oids.oid[i]);
1543 if (commit)
1544 commit->object.flags |= REACHABLE;
1545 }
1546 stop_progress(&ctx->progress);
1547
1548 /*
1549 * As this loop runs, ctx->oids.nr may grow, but not more
1550 * than the number of missing commits in the reachable
1551 * closure.
1552 */
1553 if (ctx->report_progress)
1554 ctx->progress = start_delayed_progress(
1555 the_repository,
1556 _("Expanding reachable commits in commit graph"),
1557 0);
1558 for (i = 0; i < ctx->oids.nr; i++) {
1559 display_progress(ctx->progress, i + 1);
1560 commit = lookup_commit(ctx->r, &ctx->oids.oid[i]);
1561
1562 if (!commit)
1563 continue;
1564 if (ctx->split) {
1565 if ((!repo_parse_commit(ctx->r, commit) &&
1566 commit_graph_position(commit) == COMMIT_NOT_FROM_GRAPH) ||
1567 flags == COMMIT_GRAPH_SPLIT_REPLACE)
1568 add_missing_parents(ctx, commit);
1569 } else if (!repo_parse_commit_no_graph(ctx->r, commit))
1570 add_missing_parents(ctx, commit);
1571 }
1572 stop_progress(&ctx->progress);
1573
1574 if (ctx->report_progress)
1575 ctx->progress = start_delayed_progress(
1576 the_repository,
1577 _("Clearing commit marks in commit graph"),
1578 ctx->oids.nr);
1579 for (i = 0; i < ctx->oids.nr; i++) {
1580 display_progress(ctx->progress, i + 1);
1581 commit = lookup_commit(ctx->r, &ctx->oids.oid[i]);
1582
1583 if (commit)
1584 commit->object.flags &= ~REACHABLE;
1585 }
1586 stop_progress(&ctx->progress);
1587}
1588
1589struct compute_generation_info {
1590 struct repository *r;
1591 struct packed_commit_list *commits;
1592 struct progress *progress;
1593 int progress_cnt;
1594
1595 timestamp_t (*get_generation)(struct commit *c, void *data);
1596 void (*set_generation)(struct commit *c, timestamp_t gen, void *data);
1597 void *data;
1598};
1599
1600static timestamp_t compute_generation_from_max(struct commit *c,
1601 timestamp_t max_gen,
1602 int generation_version)
1603{
1604 switch (generation_version) {
1605 case 1: /* topological levels */
1606 if (max_gen > GENERATION_NUMBER_V1_MAX - 1)
1607 max_gen = GENERATION_NUMBER_V1_MAX - 1;
1608 return max_gen + 1;
1609
1610 case 2: /* corrected commit date */
1611 if (c->date && c->date > max_gen)
1612 max_gen = c->date - 1;
1613 return max_gen + 1;
1614
1615 default:
1616 BUG("attempting unimplemented version");
1617 }
1618}
1619
1620static void compute_reachable_generation_numbers(
1621 struct compute_generation_info *info,
1622 int generation_version)
1623{
1624 int i;
1625 struct commit_list *list = NULL;
1626
1627 for (i = 0; i < info->commits->nr; i++) {
1628 struct commit *c = info->commits->list[i];
1629 timestamp_t gen;
1630 repo_parse_commit(info->r, c);
1631 gen = info->get_generation(c, info->data);
1632 display_progress(info->progress, ++info->progress_cnt);
1633
1634 if (gen != GENERATION_NUMBER_ZERO && gen != GENERATION_NUMBER_INFINITY)
1635 continue;
1636
1637 commit_list_insert(c, &list);
1638 while (list) {
1639 struct commit *current = list->item;
1640 struct commit_list *parent;
1641 int all_parents_computed = 1;
1642 uint32_t max_gen = 0;
1643
1644 for (parent = current->parents; parent; parent = parent->next) {
1645 repo_parse_commit(info->r, parent->item);
1646 gen = info->get_generation(parent->item, info->data);
1647
1648 if (gen == GENERATION_NUMBER_ZERO) {
1649 all_parents_computed = 0;
1650 commit_list_insert(parent->item, &list);
1651 break;
1652 }
1653
1654 if (gen > max_gen)
1655 max_gen = gen;
1656 }
1657
1658 if (all_parents_computed) {
1659 pop_commit(&list);
1660 gen = compute_generation_from_max(
1661 current, max_gen,
1662 generation_version);
1663 info->set_generation(current, gen, info->data);
1664 }
1665 }
1666 }
1667}
1668
1669static timestamp_t get_topo_level(struct commit *c, void *data)
1670{
1671 struct write_commit_graph_context *ctx = data;
1672 return *topo_level_slab_at(ctx->topo_levels, c);
1673}
1674
1675static void set_topo_level(struct commit *c, timestamp_t t, void *data)
1676{
1677 struct write_commit_graph_context *ctx = data;
1678 *topo_level_slab_at(ctx->topo_levels, c) = (uint32_t)t;
1679}
1680
1681static void compute_topological_levels(struct write_commit_graph_context *ctx)
1682{
1683 struct compute_generation_info info = {
1684 .r = ctx->r,
1685 .commits = &ctx->commits,
1686 .get_generation = get_topo_level,
1687 .set_generation = set_topo_level,
1688 .data = ctx,
1689 };
1690
1691 if (ctx->report_progress)
1692 info.progress = ctx->progress
1693 = start_delayed_progress(
1694 the_repository,
1695 _("Computing commit graph topological levels"),
1696 ctx->commits.nr);
1697
1698 compute_reachable_generation_numbers(&info, 1);
1699
1700 stop_progress(&ctx->progress);
1701}
1702
1703static timestamp_t get_generation_from_graph_data(struct commit *c,
1704 void *data UNUSED)
1705{
1706 return commit_graph_data_at(c)->generation;
1707}
1708
1709static void set_generation_v2(struct commit *c, timestamp_t t,
1710 void *data UNUSED)
1711{
1712 struct commit_graph_data *g = commit_graph_data_at(c);
1713 g->generation = t;
1714}
1715
1716static void compute_generation_numbers(struct write_commit_graph_context *ctx)
1717{
1718 int i;
1719 struct compute_generation_info info = {
1720 .r = ctx->r,
1721 .commits = &ctx->commits,
1722 .get_generation = get_generation_from_graph_data,
1723 .set_generation = set_generation_v2,
1724 };
1725
1726 if (ctx->report_progress)
1727 info.progress = ctx->progress
1728 = start_delayed_progress(
1729 the_repository,
1730 _("Computing commit graph generation numbers"),
1731 ctx->commits.nr);
1732
1733 if (!ctx->trust_generation_numbers) {
1734 for (i = 0; i < ctx->commits.nr; i++) {
1735 struct commit *c = ctx->commits.list[i];
1736 repo_parse_commit(ctx->r, c);
1737 commit_graph_data_at(c)->generation = GENERATION_NUMBER_ZERO;
1738 }
1739 }
1740
1741 compute_reachable_generation_numbers(&info, 2);
1742
1743 for (i = 0; i < ctx->commits.nr; i++) {
1744 struct commit *c = ctx->commits.list[i];
1745 timestamp_t offset = commit_graph_data_at(c)->generation - c->date;
1746 if (offset > GENERATION_NUMBER_V2_OFFSET_MAX)
1747 ctx->num_generation_data_overflows++;
1748 }
1749 stop_progress(&ctx->progress);
1750}
1751
1752static void set_generation_in_graph_data(struct commit *c, timestamp_t t,
1753 void *data UNUSED)
1754{
1755 commit_graph_data_at(c)->generation = t;
1756}
1757
1758/*
1759 * After this method, all commits reachable from those in the given
1760 * list will have non-zero, non-infinite generation numbers.
1761 */
1762void ensure_generations_valid(struct repository *r,
1763 struct commit **commits, size_t nr)
1764{
1765 int generation_version = get_configured_generation_version(r);
1766 struct packed_commit_list list = {
1767 .list = commits,
1768 .alloc = nr,
1769 .nr = nr,
1770 };
1771 struct compute_generation_info info = {
1772 .r = r,
1773 .commits = &list,
1774 .get_generation = get_generation_from_graph_data,
1775 .set_generation = set_generation_in_graph_data,
1776 };
1777
1778 compute_reachable_generation_numbers(&info, generation_version);
1779}
1780
1781static void trace2_bloom_filter_write_statistics(struct write_commit_graph_context *ctx)
1782{
1783 trace2_data_intmax("commit-graph", ctx->r, "filter-computed",
1784 ctx->count_bloom_filter_computed);
1785 trace2_data_intmax("commit-graph", ctx->r, "filter-not-computed",
1786 ctx->count_bloom_filter_not_computed);
1787 trace2_data_intmax("commit-graph", ctx->r, "filter-trunc-empty",
1788 ctx->count_bloom_filter_trunc_empty);
1789 trace2_data_intmax("commit-graph", ctx->r, "filter-trunc-large",
1790 ctx->count_bloom_filter_trunc_large);
1791 trace2_data_intmax("commit-graph", ctx->r, "filter-upgraded",
1792 ctx->count_bloom_filter_upgraded);
1793}
1794
1795static void compute_bloom_filters(struct write_commit_graph_context *ctx)
1796{
1797 int i;
1798 struct progress *progress = NULL;
1799 struct commit **sorted_commits;
1800 int max_new_filters;
1801
1802 init_bloom_filters();
1803
1804 if (ctx->report_progress)
1805 progress = start_delayed_progress(
1806 the_repository,
1807 _("Computing commit changed paths Bloom filters"),
1808 ctx->commits.nr);
1809
1810 DUP_ARRAY(sorted_commits, ctx->commits.list, ctx->commits.nr);
1811
1812 if (ctx->order_by_pack)
1813 QSORT(sorted_commits, ctx->commits.nr, commit_pos_cmp);
1814 else
1815 QSORT(sorted_commits, ctx->commits.nr, commit_gen_cmp);
1816
1817 max_new_filters = ctx->opts && ctx->opts->max_new_filters >= 0 ?
1818 ctx->opts->max_new_filters : ctx->commits.nr;
1819
1820 for (i = 0; i < ctx->commits.nr; i++) {
1821 enum bloom_filter_computed computed = 0;
1822 struct commit *c = sorted_commits[i];
1823 struct bloom_filter *filter = get_or_compute_bloom_filter(
1824 ctx->r,
1825 c,
1826 ctx->count_bloom_filter_computed < max_new_filters,
1827 ctx->bloom_settings,
1828 &computed);
1829 if (computed & BLOOM_COMPUTED) {
1830 ctx->count_bloom_filter_computed++;
1831 if (computed & BLOOM_TRUNC_EMPTY)
1832 ctx->count_bloom_filter_trunc_empty++;
1833 if (computed & BLOOM_TRUNC_LARGE)
1834 ctx->count_bloom_filter_trunc_large++;
1835 } else if (computed & BLOOM_UPGRADED) {
1836 ctx->count_bloom_filter_upgraded++;
1837 } else if (computed & BLOOM_NOT_COMPUTED)
1838 ctx->count_bloom_filter_not_computed++;
1839 ctx->total_bloom_filter_data_size += filter
1840 ? sizeof(unsigned char) * filter->len : 0;
1841 display_progress(progress, i + 1);
1842 }
1843
1844 if (trace2_is_enabled())
1845 trace2_bloom_filter_write_statistics(ctx);
1846
1847 free(sorted_commits);
1848 stop_progress(&progress);
1849}
1850
1851struct refs_cb_data {
1852 struct oidset *commits;
1853 struct progress *progress;
1854};
1855
1856static int add_ref_to_set(const char *refname UNUSED,
1857 const char *referent UNUSED,
1858 const struct object_id *oid,
1859 int flags UNUSED, void *cb_data)
1860{
1861 struct object_id peeled;
1862 struct refs_cb_data *data = (struct refs_cb_data *)cb_data;
1863
1864 if (!peel_iterated_oid(the_repository, oid, &peeled))
1865 oid = &peeled;
1866 if (odb_read_object_info(the_repository->objects, oid, NULL) == OBJ_COMMIT)
1867 oidset_insert(data->commits, oid);
1868
1869 display_progress(data->progress, oidset_size(data->commits));
1870
1871 return 0;
1872}
1873
1874int write_commit_graph_reachable(struct odb_source *source,
1875 enum commit_graph_write_flags flags,
1876 const struct commit_graph_opts *opts)
1877{
1878 struct oidset commits = OIDSET_INIT;
1879 struct refs_cb_data data;
1880 int result;
1881
1882 memset(&data, 0, sizeof(data));
1883 data.commits = &commits;
1884 if (flags & COMMIT_GRAPH_WRITE_PROGRESS)
1885 data.progress = start_delayed_progress(
1886 the_repository,
1887 _("Collecting referenced commits"), 0);
1888
1889 refs_for_each_ref(get_main_ref_store(the_repository), add_ref_to_set,
1890 &data);
1891
1892 stop_progress(&data.progress);
1893
1894 result = write_commit_graph(source, NULL, &commits,
1895 flags, opts);
1896
1897 oidset_clear(&commits);
1898 return result;
1899}
1900
1901static int fill_oids_from_packs(struct write_commit_graph_context *ctx,
1902 const struct string_list *pack_indexes)
1903{
1904 uint32_t i;
1905 struct strbuf progress_title = STRBUF_INIT;
1906 struct strbuf packname = STRBUF_INIT;
1907 int dirlen;
1908 int ret = 0;
1909
1910 strbuf_addf(&packname, "%s/pack/", ctx->odb_source->path);
1911 dirlen = packname.len;
1912 if (ctx->report_progress) {
1913 strbuf_addf(&progress_title,
1914 Q_("Finding commits for commit graph in %"PRIuMAX" pack",
1915 "Finding commits for commit graph in %"PRIuMAX" packs",
1916 pack_indexes->nr),
1917 (uintmax_t)pack_indexes->nr);
1918 ctx->progress = start_delayed_progress(the_repository,
1919 progress_title.buf, 0);
1920 ctx->progress_done = 0;
1921 }
1922 for (i = 0; i < pack_indexes->nr; i++) {
1923 struct packed_git *p;
1924 strbuf_setlen(&packname, dirlen);
1925 strbuf_addstr(&packname, pack_indexes->items[i].string);
1926 p = add_packed_git(ctx->r, packname.buf, packname.len, 1);
1927 if (!p) {
1928 ret = error(_("error adding pack %s"), packname.buf);
1929 goto cleanup;
1930 }
1931 if (open_pack_index(p)) {
1932 ret = error(_("error opening index for %s"), packname.buf);
1933 close_pack(p);
1934 free(p);
1935 goto cleanup;
1936 }
1937 for_each_object_in_pack(p, add_packed_commits, ctx,
1938 FOR_EACH_OBJECT_PACK_ORDER);
1939 close_pack(p);
1940 free(p);
1941 }
1942
1943cleanup:
1944 stop_progress(&ctx->progress);
1945 strbuf_release(&progress_title);
1946 strbuf_release(&packname);
1947
1948 return ret;
1949}
1950
1951static int fill_oids_from_commits(struct write_commit_graph_context *ctx,
1952 struct oidset *commits)
1953{
1954 struct oidset_iter iter;
1955 struct object_id *oid;
1956
1957 if (!oidset_size(commits))
1958 return 0;
1959
1960 oidset_iter_init(commits, &iter);
1961 while ((oid = oidset_iter_next(&iter))) {
1962 oid_array_append(&ctx->oids, oid);
1963 }
1964
1965 return 0;
1966}
1967
1968static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx)
1969{
1970 if (ctx->report_progress)
1971 ctx->progress = start_delayed_progress(
1972 the_repository,
1973 _("Finding commits for commit graph among packed objects"),
1974 ctx->approx_nr_objects);
1975 for_each_packed_object(ctx->r, add_packed_commits, ctx,
1976 FOR_EACH_OBJECT_PACK_ORDER);
1977 if (ctx->progress_done < ctx->approx_nr_objects)
1978 display_progress(ctx->progress, ctx->approx_nr_objects);
1979 stop_progress(&ctx->progress);
1980}
1981
1982static void copy_oids_to_commits(struct write_commit_graph_context *ctx)
1983{
1984 uint32_t i;
1985 enum commit_graph_split_flags flags = ctx->opts ?
1986 ctx->opts->split_flags : COMMIT_GRAPH_SPLIT_UNSPECIFIED;
1987
1988 ctx->num_extra_edges = 0;
1989 if (ctx->report_progress)
1990 ctx->progress = start_delayed_progress(
1991 the_repository,
1992 _("Finding extra edges in commit graph"),
1993 ctx->oids.nr);
1994 oid_array_sort(&ctx->oids);
1995 for (i = 0; i < ctx->oids.nr; i = oid_array_next_unique(&ctx->oids, i)) {
1996 unsigned int num_parents;
1997
1998 display_progress(ctx->progress, i + 1);
1999
2000 ALLOC_GROW(ctx->commits.list, ctx->commits.nr + 1, ctx->commits.alloc);
2001 ctx->commits.list[ctx->commits.nr] = lookup_commit(ctx->r, &ctx->oids.oid[i]);
2002
2003 if (ctx->split && flags != COMMIT_GRAPH_SPLIT_REPLACE &&
2004 commit_graph_position(ctx->commits.list[ctx->commits.nr]) != COMMIT_NOT_FROM_GRAPH)
2005 continue;
2006
2007 if (ctx->split && flags == COMMIT_GRAPH_SPLIT_REPLACE)
2008 repo_parse_commit(ctx->r, ctx->commits.list[ctx->commits.nr]);
2009 else
2010 repo_parse_commit_no_graph(ctx->r, ctx->commits.list[ctx->commits.nr]);
2011
2012 num_parents = commit_list_count(ctx->commits.list[ctx->commits.nr]->parents);
2013 if (num_parents > 2)
2014 ctx->num_extra_edges += num_parents - 1;
2015
2016 ctx->commits.nr++;
2017 }
2018 stop_progress(&ctx->progress);
2019}
2020
2021static int write_graph_chunk_base_1(struct hashfile *f,
2022 struct commit_graph *g)
2023{
2024 int num = 0;
2025
2026 if (!g)
2027 return 0;
2028
2029 num = write_graph_chunk_base_1(f, g->base_graph);
2030 hashwrite(f, g->oid.hash, the_hash_algo->rawsz);
2031 return num + 1;
2032}
2033
2034static int write_graph_chunk_base(struct hashfile *f,
2035 void *data)
2036{
2037 struct write_commit_graph_context *ctx = data;
2038 int num = write_graph_chunk_base_1(f, ctx->new_base_graph);
2039
2040 if (num != ctx->num_commit_graphs_after - 1) {
2041 error(_("failed to write correct number of base graph ids"));
2042 return -1;
2043 }
2044
2045 return 0;
2046}
2047
2048static int write_commit_graph_file(struct write_commit_graph_context *ctx)
2049{
2050 uint32_t i;
2051 struct hashfile *f;
2052 struct tempfile *graph_layer; /* when ctx->split is non-zero */
2053 struct lock_file lk = LOCK_INIT;
2054 const unsigned hashsz = the_hash_algo->rawsz;
2055 struct strbuf progress_title = STRBUF_INIT;
2056 struct chunkfile *cf;
2057 unsigned char file_hash[GIT_MAX_RAWSZ];
2058
2059 if (ctx->split) {
2060 struct strbuf tmp_file = STRBUF_INIT;
2061
2062 strbuf_addf(&tmp_file,
2063 "%s/info/commit-graphs/tmp_graph_XXXXXX",
2064 ctx->odb_source->path);
2065 ctx->graph_name = strbuf_detach(&tmp_file, NULL);
2066 } else {
2067 ctx->graph_name = get_commit_graph_filename(ctx->odb_source);
2068 }
2069
2070 if (safe_create_leading_directories(the_repository, ctx->graph_name)) {
2071 error(_("unable to create leading directories of %s"),
2072 ctx->graph_name);
2073 return -1;
2074 }
2075
2076 if (ctx->split) {
2077 char *lock_name = get_commit_graph_chain_filename(ctx->odb_source);
2078
2079 hold_lock_file_for_update_mode(&lk, lock_name,
2080 LOCK_DIE_ON_ERROR, 0444);
2081 free(lock_name);
2082
2083 graph_layer = mks_tempfile_m(ctx->graph_name, 0444);
2084 if (!graph_layer) {
2085 error(_("unable to create temporary graph layer"));
2086 return -1;
2087 }
2088
2089 if (adjust_shared_perm(the_repository, get_tempfile_path(graph_layer))) {
2090 error(_("unable to adjust shared permissions for '%s'"),
2091 get_tempfile_path(graph_layer));
2092 return -1;
2093 }
2094
2095 f = hashfd(the_repository->hash_algo,
2096 get_tempfile_fd(graph_layer), get_tempfile_path(graph_layer));
2097 } else {
2098 hold_lock_file_for_update_mode(&lk, ctx->graph_name,
2099 LOCK_DIE_ON_ERROR, 0444);
2100 f = hashfd(the_repository->hash_algo,
2101 get_lock_file_fd(&lk), get_lock_file_path(&lk));
2102 }
2103
2104 cf = init_chunkfile(f);
2105
2106 add_chunk(cf, GRAPH_CHUNKID_OIDFANOUT, GRAPH_FANOUT_SIZE,
2107 write_graph_chunk_fanout);
2108 add_chunk(cf, GRAPH_CHUNKID_OIDLOOKUP, st_mult(hashsz, ctx->commits.nr),
2109 write_graph_chunk_oids);
2110 add_chunk(cf, GRAPH_CHUNKID_DATA, st_mult(hashsz + 16, ctx->commits.nr),
2111 write_graph_chunk_data);
2112
2113 if (ctx->write_generation_data)
2114 add_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA,
2115 st_mult(sizeof(uint32_t), ctx->commits.nr),
2116 write_graph_chunk_generation_data);
2117 if (ctx->num_generation_data_overflows)
2118 add_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW,
2119 st_mult(sizeof(timestamp_t), ctx->num_generation_data_overflows),
2120 write_graph_chunk_generation_data_overflow);
2121 if (ctx->num_extra_edges)
2122 add_chunk(cf, GRAPH_CHUNKID_EXTRAEDGES,
2123 st_mult(4, ctx->num_extra_edges),
2124 write_graph_chunk_extra_edges);
2125 if (ctx->changed_paths) {
2126 add_chunk(cf, GRAPH_CHUNKID_BLOOMINDEXES,
2127 st_mult(sizeof(uint32_t), ctx->commits.nr),
2128 write_graph_chunk_bloom_indexes);
2129 add_chunk(cf, GRAPH_CHUNKID_BLOOMDATA,
2130 st_add(sizeof(uint32_t) * 3,
2131 ctx->total_bloom_filter_data_size),
2132 write_graph_chunk_bloom_data);
2133 }
2134 if (ctx->num_commit_graphs_after > 1)
2135 add_chunk(cf, GRAPH_CHUNKID_BASE,
2136 st_mult(hashsz, ctx->num_commit_graphs_after - 1),
2137 write_graph_chunk_base);
2138
2139 hashwrite_be32(f, GRAPH_SIGNATURE);
2140
2141 hashwrite_u8(f, GRAPH_VERSION);
2142 hashwrite_u8(f, oid_version(the_hash_algo));
2143 hashwrite_u8(f, get_num_chunks(cf));
2144 hashwrite_u8(f, ctx->num_commit_graphs_after - 1);
2145
2146 if (ctx->report_progress) {
2147 strbuf_addf(&progress_title,
2148 Q_("Writing out commit graph in %d pass",
2149 "Writing out commit graph in %d passes",
2150 get_num_chunks(cf)),
2151 get_num_chunks(cf));
2152 ctx->progress = start_delayed_progress(
2153 the_repository,
2154 progress_title.buf,
2155 st_mult(get_num_chunks(cf), ctx->commits.nr));
2156 }
2157
2158 write_chunkfile(cf, ctx);
2159
2160 stop_progress(&ctx->progress);
2161 strbuf_release(&progress_title);
2162
2163 if (ctx->split && ctx->base_graph_name && ctx->num_commit_graphs_after > 1) {
2164 char *new_base_hash = xstrdup(oid_to_hex(&ctx->new_base_graph->oid));
2165 char *new_base_name = get_split_graph_filename(ctx->new_base_graph->odb_source, new_base_hash);
2166
2167 free(ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 2]);
2168 free(ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 2]);
2169 ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 2] = new_base_name;
2170 ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 2] = new_base_hash;
2171 }
2172
2173 close_commit_graph(ctx->r->objects);
2174 finalize_hashfile(f, file_hash, FSYNC_COMPONENT_COMMIT_GRAPH,
2175 CSUM_HASH_IN_STREAM | CSUM_FSYNC);
2176 free_chunkfile(cf);
2177
2178 if (ctx->split) {
2179 FILE *chainf = fdopen_lock_file(&lk, "w");
2180 char *final_graph_name;
2181 int result;
2182
2183 if (!chainf) {
2184 error(_("unable to open commit-graph chain file"));
2185 return -1;
2186 }
2187
2188 if (ctx->base_graph_name) {
2189 const char *dest;
2190 int idx = ctx->num_commit_graphs_after - 1;
2191 if (ctx->num_commit_graphs_after > 1)
2192 idx--;
2193
2194 dest = ctx->commit_graph_filenames_after[idx];
2195
2196 if (strcmp(ctx->base_graph_name, dest)) {
2197 result = rename(ctx->base_graph_name, dest);
2198
2199 if (result) {
2200 error(_("failed to rename base commit-graph file"));
2201 return -1;
2202 }
2203 }
2204 } else {
2205 char *graph_name = get_commit_graph_filename(ctx->odb_source);
2206 unlink(graph_name);
2207 free(graph_name);
2208 }
2209
2210 free(ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1]);
2211 ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1] = xstrdup(hash_to_hex(file_hash));
2212 final_graph_name = get_split_graph_filename(ctx->odb_source,
2213 ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1]);
2214 free(ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 1]);
2215 ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 1] = final_graph_name;
2216
2217 result = rename_tempfile(&graph_layer, final_graph_name);
2218
2219 for (i = 0; i < ctx->num_commit_graphs_after; i++)
2220 fprintf(get_lock_file_fp(&lk), "%s\n", ctx->commit_graph_hash_after[i]);
2221
2222 if (result) {
2223 error(_("failed to rename temporary commit-graph file"));
2224 return -1;
2225 }
2226 }
2227
2228 commit_lock_file(&lk);
2229
2230 return 0;
2231}
2232
2233static void split_graph_merge_strategy(struct write_commit_graph_context *ctx)
2234{
2235 struct commit_graph *g;
2236 uint32_t num_commits;
2237 enum commit_graph_split_flags flags = COMMIT_GRAPH_SPLIT_UNSPECIFIED;
2238 uint32_t i;
2239
2240 int max_commits = 0;
2241 int size_mult = 2;
2242
2243 if (ctx->opts) {
2244 max_commits = ctx->opts->max_commits;
2245
2246 if (ctx->opts->size_multiple)
2247 size_mult = ctx->opts->size_multiple;
2248
2249 flags = ctx->opts->split_flags;
2250 }
2251
2252 g = ctx->r->objects->commit_graph;
2253 num_commits = ctx->commits.nr;
2254 if (flags == COMMIT_GRAPH_SPLIT_REPLACE)
2255 ctx->num_commit_graphs_after = 1;
2256 else
2257 ctx->num_commit_graphs_after = ctx->num_commit_graphs_before + 1;
2258
2259 if (flags != COMMIT_GRAPH_SPLIT_MERGE_PROHIBITED &&
2260 flags != COMMIT_GRAPH_SPLIT_REPLACE) {
2261 while (g && (g->num_commits <= st_mult(size_mult, num_commits) ||
2262 (max_commits && num_commits > max_commits))) {
2263 if (g->odb_source != ctx->odb_source)
2264 break;
2265
2266 if (unsigned_add_overflows(num_commits, g->num_commits))
2267 die(_("cannot merge graphs with %"PRIuMAX", "
2268 "%"PRIuMAX" commits"),
2269 (uintmax_t)num_commits,
2270 (uintmax_t)g->num_commits);
2271 num_commits += g->num_commits;
2272 g = g->base_graph;
2273
2274 ctx->num_commit_graphs_after--;
2275 }
2276 }
2277
2278 if (flags != COMMIT_GRAPH_SPLIT_REPLACE)
2279 ctx->new_base_graph = g;
2280 else if (ctx->num_commit_graphs_after != 1)
2281 BUG("split_graph_merge_strategy: num_commit_graphs_after "
2282 "should be 1 with --split=replace");
2283
2284 if (ctx->num_commit_graphs_after == 2) {
2285 char *old_graph_name = get_commit_graph_filename(g->odb_source);
2286
2287 if (!strcmp(g->filename, old_graph_name) &&
2288 g->odb_source != ctx->odb_source) {
2289 ctx->num_commit_graphs_after = 1;
2290 ctx->new_base_graph = NULL;
2291 }
2292
2293 free(old_graph_name);
2294 }
2295
2296 CALLOC_ARRAY(ctx->commit_graph_filenames_after, ctx->num_commit_graphs_after);
2297 CALLOC_ARRAY(ctx->commit_graph_hash_after, ctx->num_commit_graphs_after);
2298
2299 for (i = 0; i < ctx->num_commit_graphs_after &&
2300 i < ctx->num_commit_graphs_before; i++)
2301 ctx->commit_graph_filenames_after[i] = xstrdup(ctx->commit_graph_filenames_before[i]);
2302
2303 i = ctx->num_commit_graphs_before - 1;
2304 g = ctx->r->objects->commit_graph;
2305
2306 while (g) {
2307 if (i < ctx->num_commit_graphs_after)
2308 ctx->commit_graph_hash_after[i] = xstrdup(oid_to_hex(&g->oid));
2309
2310 /*
2311 * If the topmost remaining layer has generation data chunk, the
2312 * resultant layer also has generation data chunk.
2313 */
2314 if (i == ctx->num_commit_graphs_after - 2)
2315 ctx->write_generation_data = !!g->chunk_generation_data;
2316
2317 i--;
2318 g = g->base_graph;
2319 }
2320}
2321
2322static void merge_commit_graph(struct write_commit_graph_context *ctx,
2323 struct commit_graph *g)
2324{
2325 uint32_t i;
2326 uint32_t offset = g->num_commits_in_base;
2327
2328 if (unsigned_add_overflows(ctx->commits.nr, g->num_commits))
2329 die(_("cannot merge graph %s, too many commits: %"PRIuMAX),
2330 oid_to_hex(&g->oid),
2331 (uintmax_t)st_add(ctx->commits.nr, g->num_commits));
2332
2333 ALLOC_GROW(ctx->commits.list, ctx->commits.nr + g->num_commits, ctx->commits.alloc);
2334
2335 for (i = 0; i < g->num_commits; i++) {
2336 struct object_id oid;
2337 struct commit *result;
2338
2339 display_progress(ctx->progress, i + 1);
2340
2341 load_oid_from_graph(g, i + offset, &oid);
2342
2343 /* only add commits if they still exist in the repo */
2344 result = lookup_commit_reference_gently(ctx->r, &oid, 1);
2345
2346 if (result) {
2347 ctx->commits.list[ctx->commits.nr] = result;
2348 ctx->commits.nr++;
2349 }
2350 }
2351}
2352
2353static int commit_compare(const void *_a, const void *_b)
2354{
2355 const struct commit *a = *(const struct commit **)_a;
2356 const struct commit *b = *(const struct commit **)_b;
2357 return oidcmp(&a->object.oid, &b->object.oid);
2358}
2359
2360static void sort_and_scan_merged_commits(struct write_commit_graph_context *ctx)
2361{
2362 uint32_t i, dedup_i = 0;
2363
2364 if (ctx->report_progress)
2365 ctx->progress = start_delayed_progress(
2366 the_repository,
2367 _("Scanning merged commits"),
2368 ctx->commits.nr);
2369
2370 QSORT(ctx->commits.list, ctx->commits.nr, commit_compare);
2371
2372 ctx->num_extra_edges = 0;
2373 for (i = 0; i < ctx->commits.nr; i++) {
2374 display_progress(ctx->progress, i + 1);
2375
2376 if (i && oideq(&ctx->commits.list[i - 1]->object.oid,
2377 &ctx->commits.list[i]->object.oid)) {
2378 /*
2379 * Silently ignore duplicates. These were likely
2380 * created due to a commit appearing in multiple
2381 * layers of the chain, which is unexpected but
2382 * not invalid. We should make sure there is a
2383 * unique copy in the new layer.
2384 */
2385 } else {
2386 unsigned int num_parents;
2387
2388 ctx->commits.list[dedup_i] = ctx->commits.list[i];
2389 dedup_i++;
2390
2391 num_parents = commit_list_count(ctx->commits.list[i]->parents);
2392 if (num_parents > 2)
2393 ctx->num_extra_edges += num_parents - 1;
2394 }
2395 }
2396
2397 ctx->commits.nr = dedup_i;
2398
2399 stop_progress(&ctx->progress);
2400}
2401
2402static void merge_commit_graphs(struct write_commit_graph_context *ctx)
2403{
2404 struct commit_graph *g = ctx->r->objects->commit_graph;
2405 uint32_t current_graph_number = ctx->num_commit_graphs_before;
2406
2407 while (g && current_graph_number >= ctx->num_commit_graphs_after) {
2408 current_graph_number--;
2409
2410 if (ctx->report_progress)
2411 ctx->progress = start_delayed_progress(the_repository,
2412 _("Merging commit-graph"), 0);
2413
2414 merge_commit_graph(ctx, g);
2415 stop_progress(&ctx->progress);
2416
2417 g = g->base_graph;
2418 }
2419
2420 if (g) {
2421 ctx->new_base_graph = g;
2422 ctx->new_num_commits_in_base = g->num_commits + g->num_commits_in_base;
2423 }
2424
2425 if (ctx->new_base_graph)
2426 ctx->base_graph_name = xstrdup(ctx->new_base_graph->filename);
2427
2428 sort_and_scan_merged_commits(ctx);
2429}
2430
2431static void mark_commit_graphs(struct write_commit_graph_context *ctx)
2432{
2433 uint32_t i;
2434 time_t now = time(NULL);
2435
2436 for (i = ctx->num_commit_graphs_after - 1; i < ctx->num_commit_graphs_before; i++) {
2437 struct stat st;
2438 struct utimbuf updated_time;
2439
2440 if (stat(ctx->commit_graph_filenames_before[i], &st) < 0)
2441 continue;
2442
2443 updated_time.actime = st.st_atime;
2444 updated_time.modtime = now;
2445 utime(ctx->commit_graph_filenames_before[i], &updated_time);
2446 }
2447}
2448
2449static void expire_commit_graphs(struct write_commit_graph_context *ctx)
2450{
2451 struct strbuf path = STRBUF_INIT;
2452 DIR *dir;
2453 struct dirent *de;
2454 size_t dirnamelen;
2455 timestamp_t expire_time = time(NULL);
2456
2457 if (ctx->opts && ctx->opts->expire_time)
2458 expire_time = ctx->opts->expire_time;
2459 if (!ctx->split) {
2460 char *chain_file_name = get_commit_graph_chain_filename(ctx->odb_source);
2461 unlink(chain_file_name);
2462 free(chain_file_name);
2463 ctx->num_commit_graphs_after = 0;
2464 }
2465
2466 strbuf_addstr(&path, ctx->odb_source->path);
2467 strbuf_addstr(&path, "/info/commit-graphs");
2468 dir = opendir(path.buf);
2469
2470 if (!dir)
2471 goto out;
2472
2473 strbuf_addch(&path, '/');
2474 dirnamelen = path.len;
2475 while ((de = readdir(dir)) != NULL) {
2476 struct stat st;
2477 uint32_t i, found = 0;
2478
2479 strbuf_setlen(&path, dirnamelen);
2480 strbuf_addstr(&path, de->d_name);
2481
2482 if (stat(path.buf, &st) < 0)
2483 continue;
2484
2485 if (st.st_mtime > expire_time)
2486 continue;
2487 if (path.len < 6 || strcmp(path.buf + path.len - 6, ".graph"))
2488 continue;
2489
2490 for (i = 0; i < ctx->num_commit_graphs_after; i++) {
2491 if (!strcmp(ctx->commit_graph_filenames_after[i],
2492 path.buf)) {
2493 found = 1;
2494 break;
2495 }
2496 }
2497
2498 if (!found)
2499 unlink(path.buf);
2500 }
2501
2502out:
2503 if(dir)
2504 closedir(dir);
2505 strbuf_release(&path);
2506}
2507
2508int write_commit_graph(struct odb_source *source,
2509 const struct string_list *const pack_indexes,
2510 struct oidset *commits,
2511 enum commit_graph_write_flags flags,
2512 const struct commit_graph_opts *opts)
2513{
2514 struct repository *r = the_repository;
2515 struct write_commit_graph_context ctx = {
2516 .r = r,
2517 .odb_source = source,
2518 .append = flags & COMMIT_GRAPH_WRITE_APPEND ? 1 : 0,
2519 .report_progress = flags & COMMIT_GRAPH_WRITE_PROGRESS ? 1 : 0,
2520 .split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0,
2521 .opts = opts,
2522 .total_bloom_filter_data_size = 0,
2523 .write_generation_data = (get_configured_generation_version(r) == 2),
2524 .num_generation_data_overflows = 0,
2525 };
2526 uint32_t i;
2527 int res = 0;
2528 int replace = 0;
2529 struct bloom_filter_settings bloom_settings = DEFAULT_BLOOM_FILTER_SETTINGS;
2530 struct topo_level_slab topo_levels;
2531
2532 prepare_repo_settings(r);
2533 if (!r->settings.core_commit_graph) {
2534 warning(_("attempting to write a commit-graph, but 'core.commitGraph' is disabled"));
2535 return 0;
2536 }
2537 if (!commit_graph_compatible(r))
2538 return 0;
2539 if (r->settings.commit_graph_changed_paths_version < -1
2540 || r->settings.commit_graph_changed_paths_version > 2) {
2541 warning(_("attempting to write a commit-graph, but "
2542 "'commitGraph.changedPathsVersion' (%d) is not supported"),
2543 r->settings.commit_graph_changed_paths_version);
2544 return 0;
2545 }
2546
2547 bloom_settings.hash_version = r->settings.commit_graph_changed_paths_version;
2548 bloom_settings.bits_per_entry = git_env_ulong("GIT_TEST_BLOOM_SETTINGS_BITS_PER_ENTRY",
2549 bloom_settings.bits_per_entry);
2550 bloom_settings.num_hashes = git_env_ulong("GIT_TEST_BLOOM_SETTINGS_NUM_HASHES",
2551 bloom_settings.num_hashes);
2552 bloom_settings.max_changed_paths = git_env_ulong("GIT_TEST_BLOOM_SETTINGS_MAX_CHANGED_PATHS",
2553 bloom_settings.max_changed_paths);
2554 ctx.bloom_settings = &bloom_settings;
2555
2556 init_topo_level_slab(&topo_levels);
2557 ctx.topo_levels = &topo_levels;
2558
2559 prepare_commit_graph(ctx.r);
2560 if (ctx.r->objects->commit_graph) {
2561 struct commit_graph *g = ctx.r->objects->commit_graph;
2562
2563 while (g) {
2564 g->topo_levels = &topo_levels;
2565 g = g->base_graph;
2566 }
2567 }
2568
2569 if (flags & COMMIT_GRAPH_WRITE_BLOOM_FILTERS)
2570 ctx.changed_paths = 1;
2571 if (!(flags & COMMIT_GRAPH_NO_WRITE_BLOOM_FILTERS)) {
2572 struct commit_graph *g;
2573
2574 g = ctx.r->objects->commit_graph;
2575
2576 /* We have changed-paths already. Keep them in the next graph */
2577 if (g && g->bloom_filter_settings) {
2578 ctx.changed_paths = 1;
2579
2580 /* don't propagate the hash_version unless unspecified */
2581 if (bloom_settings.hash_version == -1)
2582 bloom_settings.hash_version = g->bloom_filter_settings->hash_version;
2583 bloom_settings.bits_per_entry = g->bloom_filter_settings->bits_per_entry;
2584 bloom_settings.num_hashes = g->bloom_filter_settings->num_hashes;
2585 bloom_settings.max_changed_paths = g->bloom_filter_settings->max_changed_paths;
2586 }
2587 }
2588
2589 bloom_settings.hash_version = bloom_settings.hash_version == 2 ? 2 : 1;
2590
2591 if (ctx.split) {
2592 struct commit_graph *g = ctx.r->objects->commit_graph;
2593
2594 while (g) {
2595 ctx.num_commit_graphs_before++;
2596 g = g->base_graph;
2597 }
2598
2599 if (ctx.num_commit_graphs_before) {
2600 ALLOC_ARRAY(ctx.commit_graph_filenames_before, ctx.num_commit_graphs_before);
2601 i = ctx.num_commit_graphs_before;
2602 g = ctx.r->objects->commit_graph;
2603
2604 while (g) {
2605 ctx.commit_graph_filenames_before[--i] = xstrdup(g->filename);
2606 g = g->base_graph;
2607 }
2608 }
2609
2610 if (ctx.opts)
2611 replace = ctx.opts->split_flags & COMMIT_GRAPH_SPLIT_REPLACE;
2612 }
2613
2614 ctx.approx_nr_objects = repo_approximate_object_count(the_repository);
2615
2616 if (ctx.append && ctx.r->objects->commit_graph) {
2617 struct commit_graph *g = ctx.r->objects->commit_graph;
2618 for (i = 0; i < g->num_commits; i++) {
2619 struct object_id oid;
2620 oidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),
2621 the_repository->hash_algo);
2622 oid_array_append(&ctx.oids, &oid);
2623 }
2624 }
2625
2626 if (pack_indexes) {
2627 ctx.order_by_pack = 1;
2628 if ((res = fill_oids_from_packs(&ctx, pack_indexes)))
2629 goto cleanup;
2630 }
2631
2632 if (commits) {
2633 if ((res = fill_oids_from_commits(&ctx, commits)))
2634 goto cleanup;
2635 }
2636
2637 if (!pack_indexes && !commits) {
2638 ctx.order_by_pack = 1;
2639 fill_oids_from_all_packs(&ctx);
2640 }
2641
2642 close_reachable(&ctx);
2643
2644 copy_oids_to_commits(&ctx);
2645
2646 if (ctx.commits.nr >= GRAPH_EDGE_LAST_MASK) {
2647 error(_("too many commits to write graph"));
2648 res = -1;
2649 goto cleanup;
2650 }
2651
2652 if (!ctx.commits.nr && !replace)
2653 goto cleanup;
2654
2655 if (ctx.split) {
2656 split_graph_merge_strategy(&ctx);
2657
2658 if (!replace)
2659 merge_commit_graphs(&ctx);
2660 } else
2661 ctx.num_commit_graphs_after = 1;
2662
2663 ctx.trust_generation_numbers = validate_mixed_generation_chain(ctx.r->objects->commit_graph);
2664
2665 compute_topological_levels(&ctx);
2666 if (ctx.write_generation_data)
2667 compute_generation_numbers(&ctx);
2668
2669 if (ctx.changed_paths)
2670 compute_bloom_filters(&ctx);
2671
2672 res = write_commit_graph_file(&ctx);
2673
2674 if (ctx.changed_paths)
2675 deinit_bloom_filters();
2676
2677 if (ctx.split)
2678 mark_commit_graphs(&ctx);
2679
2680 expire_commit_graphs(&ctx);
2681
2682cleanup:
2683 free(ctx.graph_name);
2684 free(ctx.base_graph_name);
2685 free(ctx.commits.list);
2686 oid_array_clear(&ctx.oids);
2687 clear_topo_level_slab(&topo_levels);
2688
2689 if (ctx.r->objects->commit_graph) {
2690 struct commit_graph *g = ctx.r->objects->commit_graph;
2691
2692 while (g) {
2693 g->topo_levels = NULL;
2694 g = g->base_graph;
2695 }
2696 }
2697
2698 for (i = 0; i < ctx.num_commit_graphs_before; i++)
2699 free(ctx.commit_graph_filenames_before[i]);
2700 free(ctx.commit_graph_filenames_before);
2701
2702 for (i = 0; i < ctx.num_commit_graphs_after; i++) {
2703 free(ctx.commit_graph_filenames_after[i]);
2704 free(ctx.commit_graph_hash_after[i]);
2705 }
2706 free(ctx.commit_graph_filenames_after);
2707 free(ctx.commit_graph_hash_after);
2708
2709 return res;
2710}
2711
2712#define VERIFY_COMMIT_GRAPH_ERROR_HASH 2
2713static int verify_commit_graph_error;
2714
2715__attribute__((format (printf, 1, 2)))
2716static void graph_report(const char *fmt, ...)
2717{
2718 va_list ap;
2719
2720 verify_commit_graph_error = 1;
2721 va_start(ap, fmt);
2722 vfprintf(stderr, fmt, ap);
2723 fprintf(stderr, "\n");
2724 va_end(ap);
2725}
2726
2727static int commit_graph_checksum_valid(struct commit_graph *g)
2728{
2729 return hashfile_checksum_valid(the_repository->hash_algo,
2730 g->data, g->data_len);
2731}
2732
2733static int verify_one_commit_graph(struct repository *r,
2734 struct commit_graph *g,
2735 struct progress *progress,
2736 uint64_t *seen)
2737{
2738 uint32_t i, cur_fanout_pos = 0;
2739 struct object_id prev_oid, cur_oid;
2740 struct commit *seen_gen_zero = NULL;
2741 struct commit *seen_gen_non_zero = NULL;
2742
2743 if (!commit_graph_checksum_valid(g)) {
2744 graph_report(_("the commit-graph file has incorrect checksum and is likely corrupt"));
2745 verify_commit_graph_error = VERIFY_COMMIT_GRAPH_ERROR_HASH;
2746 }
2747
2748 for (i = 0; i < g->num_commits; i++) {
2749 struct commit *graph_commit;
2750
2751 oidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),
2752 the_repository->hash_algo);
2753
2754 if (i && oidcmp(&prev_oid, &cur_oid) >= 0)
2755 graph_report(_("commit-graph has incorrect OID order: %s then %s"),
2756 oid_to_hex(&prev_oid),
2757 oid_to_hex(&cur_oid));
2758
2759 oidcpy(&prev_oid, &cur_oid);
2760
2761 while (cur_oid.hash[0] > cur_fanout_pos) {
2762 uint32_t fanout_value = get_be32(g->chunk_oid_fanout + cur_fanout_pos);
2763
2764 if (i != fanout_value)
2765 graph_report(_("commit-graph has incorrect fanout value: fanout[%d] = %u != %u"),
2766 cur_fanout_pos, fanout_value, i);
2767 cur_fanout_pos++;
2768 }
2769
2770 graph_commit = lookup_commit(r, &cur_oid);
2771 if (!parse_commit_in_graph_one(r, g, graph_commit))
2772 graph_report(_("failed to parse commit %s from commit-graph"),
2773 oid_to_hex(&cur_oid));
2774 }
2775
2776 while (cur_fanout_pos < 256) {
2777 uint32_t fanout_value = get_be32(g->chunk_oid_fanout + cur_fanout_pos);
2778
2779 if (g->num_commits != fanout_value)
2780 graph_report(_("commit-graph has incorrect fanout value: fanout[%d] = %u != %u"),
2781 cur_fanout_pos, fanout_value, i);
2782
2783 cur_fanout_pos++;
2784 }
2785
2786 if (verify_commit_graph_error & ~VERIFY_COMMIT_GRAPH_ERROR_HASH)
2787 return verify_commit_graph_error;
2788
2789 for (i = 0; i < g->num_commits; i++) {
2790 struct commit *graph_commit, *odb_commit;
2791 struct commit_list *graph_parents, *odb_parents;
2792 timestamp_t max_generation = 0;
2793 timestamp_t generation;
2794
2795 display_progress(progress, ++(*seen));
2796 oidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),
2797 the_repository->hash_algo);
2798
2799 graph_commit = lookup_commit(r, &cur_oid);
2800 odb_commit = (struct commit *)create_object(r, &cur_oid, alloc_commit_node(r));
2801 if (repo_parse_commit_internal(r, odb_commit, 0, 0)) {
2802 graph_report(_("failed to parse commit %s from object database for commit-graph"),
2803 oid_to_hex(&cur_oid));
2804 continue;
2805 }
2806
2807 if (!oideq(&get_commit_tree_in_graph_one(r, g, graph_commit)->object.oid,
2808 get_commit_tree_oid(odb_commit)))
2809 graph_report(_("root tree OID for commit %s in commit-graph is %s != %s"),
2810 oid_to_hex(&cur_oid),
2811 oid_to_hex(get_commit_tree_oid(graph_commit)),
2812 oid_to_hex(get_commit_tree_oid(odb_commit)));
2813
2814 graph_parents = graph_commit->parents;
2815 odb_parents = odb_commit->parents;
2816
2817 while (graph_parents) {
2818 if (!odb_parents) {
2819 graph_report(_("commit-graph parent list for commit %s is too long"),
2820 oid_to_hex(&cur_oid));
2821 break;
2822 }
2823
2824 /* parse parent in case it is in a base graph */
2825 parse_commit_in_graph_one(r, g, graph_parents->item);
2826
2827 if (!oideq(&graph_parents->item->object.oid, &odb_parents->item->object.oid))
2828 graph_report(_("commit-graph parent for %s is %s != %s"),
2829 oid_to_hex(&cur_oid),
2830 oid_to_hex(&graph_parents->item->object.oid),
2831 oid_to_hex(&odb_parents->item->object.oid));
2832
2833 generation = commit_graph_generation_from_graph(graph_parents->item);
2834 if (generation > max_generation)
2835 max_generation = generation;
2836
2837 graph_parents = graph_parents->next;
2838 odb_parents = odb_parents->next;
2839 }
2840
2841 if (odb_parents)
2842 graph_report(_("commit-graph parent list for commit %s terminates early"),
2843 oid_to_hex(&cur_oid));
2844
2845 if (commit_graph_generation_from_graph(graph_commit))
2846 seen_gen_non_zero = graph_commit;
2847 else
2848 seen_gen_zero = graph_commit;
2849
2850 if (seen_gen_zero)
2851 continue;
2852
2853 /*
2854 * If we are using topological level and one of our parents has
2855 * generation GENERATION_NUMBER_V1_MAX, then our generation is
2856 * also GENERATION_NUMBER_V1_MAX. Decrement to avoid extra logic
2857 * in the following condition.
2858 */
2859 if (!g->read_generation_data && max_generation == GENERATION_NUMBER_V1_MAX)
2860 max_generation--;
2861
2862 generation = commit_graph_generation(graph_commit);
2863 if (generation < max_generation + 1)
2864 graph_report(_("commit-graph generation for commit %s is %"PRItime" < %"PRItime),
2865 oid_to_hex(&cur_oid),
2866 generation,
2867 max_generation + 1);
2868
2869 if (graph_commit->date != odb_commit->date)
2870 graph_report(_("commit date for commit %s in commit-graph is %"PRItime" != %"PRItime),
2871 oid_to_hex(&cur_oid),
2872 graph_commit->date,
2873 odb_commit->date);
2874 }
2875
2876 if (seen_gen_zero && seen_gen_non_zero)
2877 graph_report(_("commit-graph has both zero and non-zero "
2878 "generations (e.g., commits '%s' and '%s')"),
2879 oid_to_hex(&seen_gen_zero->object.oid),
2880 oid_to_hex(&seen_gen_non_zero->object.oid));
2881
2882 return verify_commit_graph_error;
2883}
2884
2885int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
2886{
2887 struct progress *progress = NULL;
2888 int local_error = 0;
2889 uint64_t seen = 0;
2890
2891 if (!g) {
2892 graph_report("no commit-graph file loaded");
2893 return 1;
2894 }
2895
2896 if (flags & COMMIT_GRAPH_WRITE_PROGRESS) {
2897 uint64_t total = g->num_commits;
2898 if (!(flags & COMMIT_GRAPH_VERIFY_SHALLOW))
2899 total += g->num_commits_in_base;
2900
2901 progress = start_progress(the_repository,
2902 _("Verifying commits in commit graph"),
2903 total);
2904 }
2905
2906 for (; g; g = g->base_graph) {
2907 local_error |= verify_one_commit_graph(r, g, progress, &seen);
2908 if (flags & COMMIT_GRAPH_VERIFY_SHALLOW)
2909 break;
2910 }
2911
2912 stop_progress(&progress);
2913
2914 return local_error;
2915}
2916
2917void free_commit_graph(struct commit_graph *g)
2918{
2919 while (g) {
2920 struct commit_graph *next = g->base_graph;
2921
2922 if (g->data)
2923 munmap((void *)g->data, g->data_len);
2924 free(g->filename);
2925 free(g->bloom_filter_settings);
2926 free(g);
2927
2928 g = next;
2929 }
2930}
2931
2932void disable_commit_graph(struct repository *r)
2933{
2934 r->commit_graph_disabled = 1;
2935}