1- #include "cache.h"
2- #include "config.h"
3- #include "dir.h"
41#include "git-compat-util.h"
2+ #include "config.h"
53#include "lockfile.h"
64#include "pack.h"
75#include "packfile.h"
@@ -285,8 +283,7 @@ struct commit_graph *parse_commit_graph(void *graph_map, size_t graph_size)
285283 const unsigned char * data , * chunk_lookup ;
286284 uint32_t i ;
287285 struct commit_graph * graph ;
288- uint64_t last_chunk_offset ;
289- uint32_t last_chunk_id ;
286+ uint64_t next_chunk_offset ;
290287 uint32_t graph_signature ;
291288 unsigned char graph_version , hash_version ;
292289
@@ -326,24 +323,26 @@ struct commit_graph *parse_commit_graph(void *graph_map, size_t graph_size)
326323 graph -> data = graph_map ;
327324 graph -> data_len = graph_size ;
328325
329- last_chunk_id = 0 ;
330- last_chunk_offset = 8 ;
326+ if (graph_size < GRAPH_HEADER_SIZE +
327+ (graph -> num_chunks + 1 ) * GRAPH_CHUNKLOOKUP_WIDTH +
328+ GRAPH_FANOUT_SIZE + the_hash_algo -> rawsz ) {
329+ error (_ ("commit-graph file is too small to hold %u chunks" ),
330+ graph -> num_chunks );
331+ free (graph );
332+ return NULL ;
333+ }
334+
331335 chunk_lookup = data + 8 ;
336+ next_chunk_offset = get_be64 (chunk_lookup + 4 );
332337 for (i = 0 ; i < graph -> num_chunks ; i ++ ) {
333338 uint32_t chunk_id ;
334- uint64_t chunk_offset ;
339+ uint64_t chunk_offset = next_chunk_offset ;
335340 int chunk_repeated = 0 ;
336341
337- if (data + graph_size - chunk_lookup <
338- GRAPH_CHUNKLOOKUP_WIDTH ) {
339- error (_ ("commit-graph chunk lookup table entry missing; file may be incomplete" ));
340- goto free_and_return ;
341- }
342-
343342 chunk_id = get_be32 (chunk_lookup + 0 );
344- chunk_offset = get_be64 (chunk_lookup + 4 );
345343
346344 chunk_lookup += GRAPH_CHUNKLOOKUP_WIDTH ;
345+ next_chunk_offset = get_be64 (chunk_lookup + 4 );
347346
348347 if (chunk_offset > graph_size - the_hash_algo -> rawsz ) {
349348 error (_ ("commit-graph improper chunk offset %08x%08x" ), (uint32_t )(chunk_offset >> 32 ),
@@ -362,8 +361,11 @@ struct commit_graph *parse_commit_graph(void *graph_map, size_t graph_size)
362361 case GRAPH_CHUNKID_OIDLOOKUP :
363362 if (graph -> chunk_oid_lookup )
364363 chunk_repeated = 1 ;
365- else
364+ else {
366365 graph -> chunk_oid_lookup = data + chunk_offset ;
366+ graph -> num_commits = (next_chunk_offset - chunk_offset )
367+ / graph -> hash_len ;
368+ }
367369 break ;
368370
369371 case GRAPH_CHUNKID_DATA :
@@ -417,15 +419,6 @@ struct commit_graph *parse_commit_graph(void *graph_map, size_t graph_size)
417419 error (_ ("commit-graph chunk id %08x appears multiple times" ), chunk_id );
418420 goto free_and_return ;
419421 }
420-
421- if (last_chunk_id == GRAPH_CHUNKID_OIDLOOKUP )
422- {
423- graph -> num_commits = (chunk_offset - last_chunk_offset )
424- / graph -> hash_len ;
425- }
426-
427- last_chunk_id = chunk_id ;
428- last_chunk_offset = chunk_offset ;
429422 }
430423
431424 if (graph -> chunk_bloom_indexes && graph -> chunk_bloom_data ) {
@@ -1586,17 +1579,22 @@ static int write_graph_chunk_base(struct hashfile *f,
15861579 return 0 ;
15871580}
15881581
1582+ struct chunk_info {
1583+ uint32_t id ;
1584+ uint64_t size ;
1585+ };
1586+
15891587static int write_commit_graph_file (struct write_commit_graph_context * ctx )
15901588{
15911589 uint32_t i ;
15921590 int fd ;
15931591 struct hashfile * f ;
15941592 struct lock_file lk = LOCK_INIT ;
1595- uint32_t chunk_ids [MAX_NUM_CHUNKS + 1 ];
1596- uint64_t chunk_offsets [MAX_NUM_CHUNKS + 1 ];
1593+ struct chunk_info chunks [MAX_NUM_CHUNKS + 1 ];
15971594 const unsigned hashsz = the_hash_algo -> rawsz ;
15981595 struct strbuf progress_title = STRBUF_INIT ;
15991596 int num_chunks = 3 ;
1597+ uint64_t chunk_offset ;
16001598 struct object_id file_hash ;
16011599 const struct bloom_filter_settings bloom_settings = DEFAULT_BLOOM_FILTER_SETTINGS ;
16021600
@@ -1644,51 +1642,34 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
16441642 f = hashfd (lk .tempfile -> fd , lk .tempfile -> filename .buf );
16451643 }
16461644
1647- chunk_ids [0 ] = GRAPH_CHUNKID_OIDFANOUT ;
1648- chunk_ids [1 ] = GRAPH_CHUNKID_OIDLOOKUP ;
1649- chunk_ids [2 ] = GRAPH_CHUNKID_DATA ;
1645+ chunks [0 ].id = GRAPH_CHUNKID_OIDFANOUT ;
1646+ chunks [0 ].size = GRAPH_FANOUT_SIZE ;
1647+ chunks [1 ].id = GRAPH_CHUNKID_OIDLOOKUP ;
1648+ chunks [1 ].size = hashsz * ctx -> commits .nr ;
1649+ chunks [2 ].id = GRAPH_CHUNKID_DATA ;
1650+ chunks [2 ].size = (hashsz + 16 ) * ctx -> commits .nr ;
16501651 if (ctx -> num_extra_edges ) {
1651- chunk_ids [num_chunks ] = GRAPH_CHUNKID_EXTRAEDGES ;
1652+ chunks [num_chunks ].id = GRAPH_CHUNKID_EXTRAEDGES ;
1653+ chunks [num_chunks ].size = 4 * ctx -> num_extra_edges ;
16521654 num_chunks ++ ;
16531655 }
16541656 if (ctx -> changed_paths ) {
1655- chunk_ids [num_chunks ] = GRAPH_CHUNKID_BLOOMINDEXES ;
1657+ chunks [num_chunks ].id = GRAPH_CHUNKID_BLOOMINDEXES ;
1658+ chunks [num_chunks ].size = sizeof (uint32_t ) * ctx -> commits .nr ;
16561659 num_chunks ++ ;
1657- chunk_ids [num_chunks ] = GRAPH_CHUNKID_BLOOMDATA ;
1660+ chunks [num_chunks ].id = GRAPH_CHUNKID_BLOOMDATA ;
1661+ chunks [num_chunks ].size = sizeof (uint32_t ) * 3
1662+ + ctx -> total_bloom_filter_data_size ;
16581663 num_chunks ++ ;
16591664 }
16601665 if (ctx -> num_commit_graphs_after > 1 ) {
1661- chunk_ids [num_chunks ] = GRAPH_CHUNKID_BASE ;
1666+ chunks [num_chunks ].id = GRAPH_CHUNKID_BASE ;
1667+ chunks [num_chunks ].size = hashsz * (ctx -> num_commit_graphs_after - 1 );
16621668 num_chunks ++ ;
16631669 }
16641670
1665- chunk_ids [num_chunks ] = 0 ;
1666-
1667- chunk_offsets [0 ] = 8 + (num_chunks + 1 ) * GRAPH_CHUNKLOOKUP_WIDTH ;
1668- chunk_offsets [1 ] = chunk_offsets [0 ] + GRAPH_FANOUT_SIZE ;
1669- chunk_offsets [2 ] = chunk_offsets [1 ] + hashsz * ctx -> commits .nr ;
1670- chunk_offsets [3 ] = chunk_offsets [2 ] + (hashsz + 16 ) * ctx -> commits .nr ;
1671-
1672- num_chunks = 3 ;
1673- if (ctx -> num_extra_edges ) {
1674- chunk_offsets [num_chunks + 1 ] = chunk_offsets [num_chunks ] +
1675- 4 * ctx -> num_extra_edges ;
1676- num_chunks ++ ;
1677- }
1678- if (ctx -> changed_paths ) {
1679- chunk_offsets [num_chunks + 1 ] = chunk_offsets [num_chunks ] +
1680- sizeof (uint32_t ) * ctx -> commits .nr ;
1681- num_chunks ++ ;
1682-
1683- chunk_offsets [num_chunks + 1 ] = chunk_offsets [num_chunks ] +
1684- sizeof (uint32_t ) * 3 + ctx -> total_bloom_filter_data_size ;
1685- num_chunks ++ ;
1686- }
1687- if (ctx -> num_commit_graphs_after > 1 ) {
1688- chunk_offsets [num_chunks + 1 ] = chunk_offsets [num_chunks ] +
1689- hashsz * (ctx -> num_commit_graphs_after - 1 );
1690- num_chunks ++ ;
1691- }
1671+ chunks [num_chunks ].id = 0 ;
1672+ chunks [num_chunks ].size = 0 ;
16921673
16931674 hashwrite_be32 (f , GRAPH_SIGNATURE );
16941675
@@ -1697,13 +1678,16 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
16971678 hashwrite_u8 (f , num_chunks );
16981679 hashwrite_u8 (f , ctx -> num_commit_graphs_after - 1 );
16991680
1681+ chunk_offset = 8 + (num_chunks + 1 ) * GRAPH_CHUNKLOOKUP_WIDTH ;
17001682 for (i = 0 ; i <= num_chunks ; i ++ ) {
17011683 uint32_t chunk_write [3 ];
17021684
1703- chunk_write [0 ] = htonl (chunk_ids [i ]);
1704- chunk_write [1 ] = htonl (chunk_offsets [ i ] >> 32 );
1705- chunk_write [2 ] = htonl (chunk_offsets [ i ] & 0xffffffff );
1685+ chunk_write [0 ] = htonl (chunks [i ]. id );
1686+ chunk_write [1 ] = htonl (chunk_offset >> 32 );
1687+ chunk_write [2 ] = htonl (chunk_offset & 0xffffffff );
17061688 hashwrite (f , chunk_write , 12 );
1689+
1690+ chunk_offset += chunks [i ].size ;
17071691 }
17081692
17091693 if (ctx -> report_progress ) {
0 commit comments