@@ -1291,36 +1291,6 @@ static int write_graph_chunk_base(struct hashfile *f,
1291
1291
return 0 ;
1292
1292
}
1293
1293
1294
- static void init_commit_graph_chain (struct write_commit_graph_context * ctx )
1295
- {
1296
- struct commit_graph * g = ctx -> r -> objects -> commit_graph ;
1297
- uint32_t i ;
1298
-
1299
- ctx -> new_base_graph = g ;
1300
- ctx -> base_graph_name = xstrdup (g -> filename );
1301
- ctx -> new_num_commits_in_base = g -> num_commits + g -> num_commits_in_base ;
1302
-
1303
- ctx -> num_commit_graphs_after = ctx -> num_commit_graphs_before + 1 ;
1304
-
1305
- ALLOC_ARRAY (ctx -> commit_graph_filenames_after , ctx -> num_commit_graphs_after );
1306
- ALLOC_ARRAY (ctx -> commit_graph_hash_after , ctx -> num_commit_graphs_after );
1307
-
1308
- for (i = 0 ; i < ctx -> num_commit_graphs_before - 1 ; i ++ )
1309
- ctx -> commit_graph_filenames_after [i ] = xstrdup (ctx -> commit_graph_filenames_before [i ]);
1310
-
1311
- if (ctx -> num_commit_graphs_before )
1312
- ctx -> commit_graph_filenames_after [ctx -> num_commit_graphs_before - 1 ] =
1313
- get_split_graph_filename (ctx -> obj_dir , oid_to_hex (& g -> oid ));
1314
-
1315
- i = ctx -> num_commit_graphs_before - 1 ;
1316
-
1317
- while (g ) {
1318
- ctx -> commit_graph_hash_after [i ] = xstrdup (oid_to_hex (& g -> oid ));
1319
- i -- ;
1320
- g = g -> base_graph ;
1321
- }
1322
- }
1323
-
1324
1294
static int write_commit_graph_file (struct write_commit_graph_context * ctx )
1325
1295
{
1326
1296
uint32_t i ;
@@ -1498,6 +1468,149 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
1498
1468
return 0 ;
1499
1469
}
1500
1470
1471
+ static int split_strategy_max_commits = 64000 ;
1472
+ static float split_strategy_size_mult = 2.0f ;
1473
+
1474
+ static void split_graph_merge_strategy (struct write_commit_graph_context * ctx )
1475
+ {
1476
+ struct commit_graph * g = ctx -> r -> objects -> commit_graph ;
1477
+ uint32_t num_commits = ctx -> commits .nr ;
1478
+ uint32_t i ;
1479
+
1480
+ g = ctx -> r -> objects -> commit_graph ;
1481
+ ctx -> num_commit_graphs_after = ctx -> num_commit_graphs_before + 1 ;
1482
+
1483
+ while (g && (g -> num_commits <= split_strategy_size_mult * num_commits ||
1484
+ num_commits > split_strategy_max_commits )) {
1485
+ num_commits += g -> num_commits ;
1486
+ g = g -> base_graph ;
1487
+
1488
+ ctx -> num_commit_graphs_after -- ;
1489
+ }
1490
+
1491
+ ctx -> new_base_graph = g ;
1492
+
1493
+ ALLOC_ARRAY (ctx -> commit_graph_filenames_after , ctx -> num_commit_graphs_after );
1494
+ ALLOC_ARRAY (ctx -> commit_graph_hash_after , ctx -> num_commit_graphs_after );
1495
+
1496
+ for (i = 0 ; i < ctx -> num_commit_graphs_after &&
1497
+ i < ctx -> num_commit_graphs_before ; i ++ )
1498
+ ctx -> commit_graph_filenames_after [i ] = xstrdup (ctx -> commit_graph_filenames_before [i ]);
1499
+
1500
+ i = ctx -> num_commit_graphs_before - 1 ;
1501
+ g = ctx -> r -> objects -> commit_graph ;
1502
+
1503
+ while (g ) {
1504
+ if (i < ctx -> num_commit_graphs_after )
1505
+ ctx -> commit_graph_hash_after [i ] = xstrdup (oid_to_hex (& g -> oid ));
1506
+
1507
+ i -- ;
1508
+ g = g -> base_graph ;
1509
+ }
1510
+ }
1511
+
1512
+ static void merge_commit_graph (struct write_commit_graph_context * ctx ,
1513
+ struct commit_graph * g )
1514
+ {
1515
+ uint32_t i ;
1516
+ uint32_t offset = g -> num_commits_in_base ;
1517
+
1518
+ ALLOC_GROW (ctx -> commits .list , ctx -> commits .nr + g -> num_commits , ctx -> commits .alloc );
1519
+
1520
+ for (i = 0 ; i < g -> num_commits ; i ++ ) {
1521
+ struct object_id oid ;
1522
+ struct commit * result ;
1523
+
1524
+ display_progress (ctx -> progress , i + 1 );
1525
+
1526
+ load_oid_from_graph (g , i + offset , & oid );
1527
+
1528
+ /* only add commits if they still exist in the repo */
1529
+ result = lookup_commit_reference_gently (ctx -> r , & oid , 1 );
1530
+
1531
+ if (result ) {
1532
+ ctx -> commits .list [ctx -> commits .nr ] = result ;
1533
+ ctx -> commits .nr ++ ;
1534
+ }
1535
+ }
1536
+ }
1537
+
1538
+ static int commit_compare (const void * _a , const void * _b )
1539
+ {
1540
+ const struct commit * a = * (const struct commit * * )_a ;
1541
+ const struct commit * b = * (const struct commit * * )_b ;
1542
+ return oidcmp (& a -> object .oid , & b -> object .oid );
1543
+ }
1544
+
1545
+ static void deduplicate_commits (struct write_commit_graph_context * ctx )
1546
+ {
1547
+ uint32_t i , num_parents , last_distinct = 0 , duplicates = 0 ;
1548
+ struct commit_list * parent ;
1549
+
1550
+ if (ctx -> report_progress )
1551
+ ctx -> progress = start_delayed_progress (
1552
+ _ ("De-duplicating merged commits" ),
1553
+ ctx -> commits .nr );
1554
+
1555
+ QSORT (ctx -> commits .list , ctx -> commits .nr , commit_compare );
1556
+
1557
+ ctx -> num_extra_edges = 0 ;
1558
+ for (i = 1 ; i < ctx -> commits .nr ; i ++ ) {
1559
+ display_progress (ctx -> progress , i );
1560
+
1561
+ if (oideq (& ctx -> commits .list [last_distinct ]-> object .oid ,
1562
+ & ctx -> commits .list [i ]-> object .oid )) {
1563
+ duplicates ++ ;
1564
+ } else {
1565
+ if (duplicates )
1566
+ ctx -> commits .list [last_distinct + 1 ] = ctx -> commits .list [i ];
1567
+ last_distinct ++ ;
1568
+
1569
+ num_parents = 0 ;
1570
+ for (parent = ctx -> commits .list [i ]-> parents ; parent ; parent = parent -> next )
1571
+ num_parents ++ ;
1572
+
1573
+ if (num_parents > 2 )
1574
+ ctx -> num_extra_edges += num_parents - 2 ;
1575
+ }
1576
+ }
1577
+
1578
+ ctx -> commits .nr -= duplicates ;
1579
+ stop_progress (& ctx -> progress );
1580
+ }
1581
+
1582
+ static void merge_commit_graphs (struct write_commit_graph_context * ctx )
1583
+ {
1584
+ struct commit_graph * g = ctx -> r -> objects -> commit_graph ;
1585
+ uint32_t current_graph_number = ctx -> num_commit_graphs_before ;
1586
+ struct strbuf progress_title = STRBUF_INIT ;
1587
+
1588
+ while (g && current_graph_number >= ctx -> num_commit_graphs_after ) {
1589
+ current_graph_number -- ;
1590
+
1591
+ if (ctx -> report_progress ) {
1592
+ strbuf_addstr (& progress_title , _ ("Merging commit-graph" ));
1593
+ ctx -> progress = start_delayed_progress (progress_title .buf , 0 );
1594
+ }
1595
+
1596
+ merge_commit_graph (ctx , g );
1597
+ stop_progress (& ctx -> progress );
1598
+ strbuf_release (& progress_title );
1599
+
1600
+ g = g -> base_graph ;
1601
+ }
1602
+
1603
+ if (g ) {
1604
+ ctx -> new_base_graph = g ;
1605
+ ctx -> new_num_commits_in_base = g -> num_commits + g -> num_commits_in_base ;
1606
+ }
1607
+
1608
+ if (ctx -> new_base_graph )
1609
+ ctx -> base_graph_name = xstrdup (ctx -> new_base_graph -> filename );
1610
+
1611
+ deduplicate_commits (ctx );
1612
+ }
1613
+
1501
1614
int write_commit_graph (const char * obj_dir ,
1502
1615
struct string_list * pack_indexes ,
1503
1616
struct string_list * commit_hex ,
@@ -1543,6 +1656,9 @@ int write_commit_graph(const char *obj_dir,
1543
1656
ctx -> approx_nr_objects = approximate_object_count ();
1544
1657
ctx -> oids .alloc = ctx -> approx_nr_objects / 32 ;
1545
1658
1659
+ if (ctx -> split && ctx -> oids .alloc > split_strategy_max_commits )
1660
+ ctx -> oids .alloc = split_strategy_max_commits ;
1661
+
1546
1662
if (ctx -> append ) {
1547
1663
prepare_commit_graph_one (ctx -> r , ctx -> obj_dir );
1548
1664
if (ctx -> r -> objects -> commit_graph )
@@ -1596,9 +1712,11 @@ int write_commit_graph(const char *obj_dir,
1596
1712
if (!ctx -> commits .nr )
1597
1713
goto cleanup ;
1598
1714
1599
- if (ctx -> split )
1600
- init_commit_graph_chain (ctx );
1601
- else
1715
+ if (ctx -> split ) {
1716
+ split_graph_merge_strategy (ctx );
1717
+
1718
+ merge_commit_graphs (ctx );
1719
+ } else
1602
1720
ctx -> num_commit_graphs_after = 1 ;
1603
1721
1604
1722
compute_generation_numbers (ctx );
0 commit comments