Skip to content

Commit 118bd57

Browse files
derrickstoleegitster
authored andcommitted
commit-graph: add base graphs chunk
To quickly verify a commit-graph chain is valid on load, we will read from the new "Base Graphs Chunk" of each file in the chain. This will prevent accidentally loading incorrect data from manually editing the commit-graph-chain file or renaming graph-{hash}.graph files. The commit_graph struct already had an object_id struct "oid", but it was never initialized or used. Add a line to read the hash from the end of the commit-graph file and into the oid member. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5c84b33 commit 118bd57

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

Documentation/technical/commit-graph-format.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ HEADER:
4444

4545
1-byte number (C) of "chunks"
4646

47-
1-byte (reserved for later use)
48-
Current clients should ignore this value.
47+
1-byte number (B) of base commit-graphs
48+
We infer the length (H*B) of the Base Graphs chunk
49+
from this value.
4950

5051
CHUNK LOOKUP:
5152

@@ -92,6 +93,12 @@ CHUNK DATA:
9293
positions for the parents until reaching a value with the most-significant
9394
bit on. The other bits correspond to the position of the last parent.
9495

96+
Base Graphs List (ID: {'B', 'A', 'S', 'E'}) [Optional]
97+
This list of H-byte hashes describe a set of B commit-graph files that
98+
form a commit-graph chain. The graph position for the ith commit in this
99+
file's OID Lookup chunk is equal to i plus the number of commits in all
100+
base graphs. If B is non-zero, this chunk must exist.
101+
95102
TRAILER:
96103

97104
H-byte HASH-checksum of all of the above.

commit-graph.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#define GRAPH_CHUNKID_OIDLOOKUP 0x4f49444c /* "OIDL" */
2323
#define GRAPH_CHUNKID_DATA 0x43444154 /* "CDAT" */
2424
#define GRAPH_CHUNKID_EXTRAEDGES 0x45444745 /* "EDGE" */
25+
#define GRAPH_CHUNKID_BASE 0x42415345 /* "BASE" */
2526

2627
#define GRAPH_DATA_WIDTH (the_hash_algo->rawsz + 16)
2728

@@ -262,6 +263,12 @@ struct commit_graph *parse_commit_graph(void *graph_map, int fd,
262263
else
263264
graph->chunk_extra_edges = data + chunk_offset;
264265
break;
266+
267+
case GRAPH_CHUNKID_BASE:
268+
if (graph->chunk_base_graphs)
269+
chunk_repeated = 1;
270+
else
271+
graph->chunk_base_graphs = data + chunk_offset;
265272
}
266273

267274
if (chunk_repeated) {
@@ -280,6 +287,8 @@ struct commit_graph *parse_commit_graph(void *graph_map, int fd,
280287
last_chunk_offset = chunk_offset;
281288
}
282289

290+
hashcpy(graph->oid.hash, graph->data + graph->data_len - graph->hash_len);
291+
283292
if (verify_commit_graph_lite(graph))
284293
return NULL;
285294

@@ -315,8 +324,21 @@ static int add_graph_to_chain(struct commit_graph *g,
315324
{
316325
struct commit_graph *cur_g = chain;
317326

327+
if (n && !g->chunk_base_graphs) {
328+
warning(_("commit-graph has no base graphs chunk"));
329+
return 0;
330+
}
331+
318332
while (n) {
319333
n--;
334+
335+
if (!cur_g ||
336+
!oideq(&oids[n], &cur_g->oid) ||
337+
!hasheq(oids[n].hash, g->chunk_base_graphs + g->hash_len * n)) {
338+
warning(_("commit-graph chain does not match"));
339+
return 0;
340+
}
341+
320342
cur_g = cur_g->base_graph;
321343
}
322344

commit-graph.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct commit_graph {
5555
const unsigned char *chunk_oid_lookup;
5656
const unsigned char *chunk_commit_data;
5757
const unsigned char *chunk_extra_edges;
58+
const unsigned char *chunk_base_graphs;
5859
};
5960

6061
struct commit_graph *load_commit_graph_one_fd_st(int fd, struct stat *st);

0 commit comments

Comments
 (0)