1
- #include "cache.h"
2
- #include "config.h"
3
- #include "dir.h"
4
1
#include "git-compat-util.h"
2
+ #include "config.h"
5
3
#include "lockfile.h"
6
4
#include "pack.h"
7
5
#include "packfile.h"
@@ -285,8 +283,7 @@ struct commit_graph *parse_commit_graph(void *graph_map, size_t graph_size)
285
283
const unsigned char * data , * chunk_lookup ;
286
284
uint32_t i ;
287
285
struct commit_graph * graph ;
288
- uint64_t last_chunk_offset ;
289
- uint32_t last_chunk_id ;
286
+ uint64_t next_chunk_offset ;
290
287
uint32_t graph_signature ;
291
288
unsigned char graph_version , hash_version ;
292
289
@@ -326,24 +323,26 @@ struct commit_graph *parse_commit_graph(void *graph_map, size_t graph_size)
326
323
graph -> data = graph_map ;
327
324
graph -> data_len = graph_size ;
328
325
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
+
331
335
chunk_lookup = data + 8 ;
336
+ next_chunk_offset = get_be64 (chunk_lookup + 4 );
332
337
for (i = 0 ; i < graph -> num_chunks ; i ++ ) {
333
338
uint32_t chunk_id ;
334
- uint64_t chunk_offset ;
339
+ uint64_t chunk_offset = next_chunk_offset ;
335
340
int chunk_repeated = 0 ;
336
341
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
-
343
342
chunk_id = get_be32 (chunk_lookup + 0 );
344
- chunk_offset = get_be64 (chunk_lookup + 4 );
345
343
346
344
chunk_lookup += GRAPH_CHUNKLOOKUP_WIDTH ;
345
+ next_chunk_offset = get_be64 (chunk_lookup + 4 );
347
346
348
347
if (chunk_offset > graph_size - the_hash_algo -> rawsz ) {
349
348
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)
362
361
case GRAPH_CHUNKID_OIDLOOKUP :
363
362
if (graph -> chunk_oid_lookup )
364
363
chunk_repeated = 1 ;
365
- else
364
+ else {
366
365
graph -> chunk_oid_lookup = data + chunk_offset ;
366
+ graph -> num_commits = (next_chunk_offset - chunk_offset )
367
+ / graph -> hash_len ;
368
+ }
367
369
break ;
368
370
369
371
case GRAPH_CHUNKID_DATA :
@@ -417,15 +419,6 @@ struct commit_graph *parse_commit_graph(void *graph_map, size_t graph_size)
417
419
error (_ ("commit-graph chunk id %08x appears multiple times" ), chunk_id );
418
420
goto free_and_return ;
419
421
}
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 ;
429
422
}
430
423
431
424
if (graph -> chunk_bloom_indexes && graph -> chunk_bloom_data ) {
@@ -1586,17 +1579,22 @@ static int write_graph_chunk_base(struct hashfile *f,
1586
1579
return 0 ;
1587
1580
}
1588
1581
1582
+ struct chunk_info {
1583
+ uint32_t id ;
1584
+ uint64_t size ;
1585
+ };
1586
+
1589
1587
static int write_commit_graph_file (struct write_commit_graph_context * ctx )
1590
1588
{
1591
1589
uint32_t i ;
1592
1590
int fd ;
1593
1591
struct hashfile * f ;
1594
1592
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 ];
1597
1594
const unsigned hashsz = the_hash_algo -> rawsz ;
1598
1595
struct strbuf progress_title = STRBUF_INIT ;
1599
1596
int num_chunks = 3 ;
1597
+ uint64_t chunk_offset ;
1600
1598
struct object_id file_hash ;
1601
1599
const struct bloom_filter_settings bloom_settings = DEFAULT_BLOOM_FILTER_SETTINGS ;
1602
1600
@@ -1644,51 +1642,34 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
1644
1642
f = hashfd (lk .tempfile -> fd , lk .tempfile -> filename .buf );
1645
1643
}
1646
1644
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 ;
1650
1651
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 ;
1652
1654
num_chunks ++ ;
1653
1655
}
1654
1656
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 ;
1656
1659
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 ;
1658
1663
num_chunks ++ ;
1659
1664
}
1660
1665
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 );
1662
1668
num_chunks ++ ;
1663
1669
}
1664
1670
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 ;
1692
1673
1693
1674
hashwrite_be32 (f , GRAPH_SIGNATURE );
1694
1675
@@ -1697,13 +1678,16 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
1697
1678
hashwrite_u8 (f , num_chunks );
1698
1679
hashwrite_u8 (f , ctx -> num_commit_graphs_after - 1 );
1699
1680
1681
+ chunk_offset = 8 + (num_chunks + 1 ) * GRAPH_CHUNKLOOKUP_WIDTH ;
1700
1682
for (i = 0 ; i <= num_chunks ; i ++ ) {
1701
1683
uint32_t chunk_write [3 ];
1702
1684
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 );
1706
1688
hashwrite (f , chunk_write , 12 );
1689
+
1690
+ chunk_offset += chunks [i ].size ;
1707
1691
}
1708
1692
1709
1693
if (ctx -> report_progress ) {
0 commit comments