@@ -1443,6 +1443,72 @@ static int module_clone(int argc, const char **argv, const char *prefix)
1443
1443
return 0 ;
1444
1444
}
1445
1445
1446
+ static void determine_submodule_update_strategy (struct repository * r ,
1447
+ int just_cloned ,
1448
+ const char * path ,
1449
+ const char * update ,
1450
+ struct submodule_update_strategy * out )
1451
+ {
1452
+ const struct submodule * sub = submodule_from_path (r , & null_oid , path );
1453
+ char * key ;
1454
+ const char * val ;
1455
+
1456
+ key = xstrfmt ("submodule.%s.update" , sub -> name );
1457
+
1458
+ if (update ) {
1459
+ trace_printf ("parsing update" );
1460
+ if (parse_submodule_update_strategy (update , out ) < 0 )
1461
+ die (_ ("Invalid update mode '%s' for submodule path '%s'" ),
1462
+ update , path );
1463
+ } else if (!repo_config_get_string_const (r , key , & val )) {
1464
+ if (parse_submodule_update_strategy (val , out ) < 0 )
1465
+ die (_ ("Invalid update mode '%s' configured for submodule path '%s'" ),
1466
+ val , path );
1467
+ } else if (sub -> update_strategy .type != SM_UPDATE_UNSPECIFIED ) {
1468
+ trace_printf ("loaded thing" );
1469
+ out -> type = sub -> update_strategy .type ;
1470
+ out -> command = sub -> update_strategy .command ;
1471
+ } else
1472
+ out -> type = SM_UPDATE_CHECKOUT ;
1473
+
1474
+ if (just_cloned &&
1475
+ (out -> type == SM_UPDATE_MERGE ||
1476
+ out -> type == SM_UPDATE_REBASE ||
1477
+ out -> type == SM_UPDATE_NONE ))
1478
+ out -> type = SM_UPDATE_CHECKOUT ;
1479
+
1480
+ free (key );
1481
+ }
1482
+
1483
+ static int module_update_module_mode (int argc , const char * * argv , const char * prefix )
1484
+ {
1485
+ const char * path , * update = NULL ;
1486
+ int just_cloned ;
1487
+ struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT };
1488
+
1489
+ if (argc < 3 || argc > 4 )
1490
+ die ("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]" );
1491
+
1492
+ just_cloned = git_config_int ("just_cloned" , argv [1 ]);
1493
+ path = argv [2 ];
1494
+
1495
+ if (argc == 4 )
1496
+ update = argv [3 ];
1497
+
1498
+ determine_submodule_update_strategy (the_repository ,
1499
+ just_cloned , path , update ,
1500
+ & update_strategy );
1501
+ fputs (submodule_strategy_to_string (& update_strategy ), stdout );
1502
+
1503
+ return 0 ;
1504
+ }
1505
+
1506
+ struct update_clone_data {
1507
+ const struct submodule * sub ;
1508
+ struct object_id oid ;
1509
+ unsigned just_cloned ;
1510
+ };
1511
+
1446
1512
struct submodule_update_clone {
1447
1513
/* index into 'list', the list of submodules to look into for cloning */
1448
1514
int current ;
@@ -1462,20 +1528,23 @@ struct submodule_update_clone {
1462
1528
const char * recursive_prefix ;
1463
1529
const char * prefix ;
1464
1530
1465
- /* Machine-readable status lines to be consumed by git-submodule.sh */
1466
- struct string_list projectlines ;
1531
+ /* to be consumed by git-submodule.sh */
1532
+ struct update_clone_data * update_clone ;
1533
+ int update_clone_nr ; int update_clone_alloc ;
1467
1534
1468
1535
/* If we want to stop as fast as possible and return an error */
1469
1536
unsigned quickstop : 1 ;
1470
1537
1471
1538
/* failed clones to be retried again */
1472
1539
const struct cache_entry * * failed_clones ;
1473
1540
int failed_clones_nr , failed_clones_alloc ;
1541
+
1542
+ int max_jobs ;
1474
1543
};
1475
1544
#define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
1476
1545
SUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, 0, \
1477
1546
NULL, NULL, NULL, \
1478
- STRING_LIST_INIT_DUP , 0, NULL, 0, 0}
1547
+ NULL , 0, 0, 0, NULL, 0 , 0, 0}
1479
1548
1480
1549
1481
1550
static void next_submodule_warn_missing (struct submodule_update_clone * suc ,
@@ -1569,11 +1638,12 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
1569
1638
strbuf_addf (& sb , "%s/.git" , ce -> name );
1570
1639
needs_cloning = !file_exists (sb .buf );
1571
1640
1572
- strbuf_reset (& sb );
1573
- strbuf_addf (& sb , "%06o %s %d %d\t%s\n" , ce -> ce_mode ,
1574
- oid_to_hex (& ce -> oid ), ce_stage (ce ),
1575
- needs_cloning , ce -> name );
1576
- string_list_append (& suc -> projectlines , sb .buf );
1641
+ ALLOC_GROW (suc -> update_clone , suc -> update_clone_nr + 1 ,
1642
+ suc -> update_clone_alloc );
1643
+ oidcpy (& suc -> update_clone [suc -> update_clone_nr ].oid , & ce -> oid );
1644
+ suc -> update_clone [suc -> update_clone_nr ].just_cloned = needs_cloning ;
1645
+ suc -> update_clone [suc -> update_clone_nr ].sub = sub ;
1646
+ suc -> update_clone_nr ++ ;
1577
1647
1578
1648
if (!needs_cloning )
1579
1649
goto cleanup ;
@@ -1714,11 +1784,44 @@ static int git_update_clone_config(const char *var, const char *value,
1714
1784
return 0 ;
1715
1785
}
1716
1786
1787
+ static void update_submodule (struct update_clone_data * ucd )
1788
+ {
1789
+ fprintf (stdout , "dummy %s %d\t%s\n" ,
1790
+ oid_to_hex (& ucd -> oid ),
1791
+ ucd -> just_cloned ,
1792
+ ucd -> sub -> path );
1793
+ }
1794
+
1795
+ static int update_submodules (struct submodule_update_clone * suc )
1796
+ {
1797
+ int i ;
1798
+
1799
+ run_processes_parallel (suc -> max_jobs ,
1800
+ update_clone_get_next_task ,
1801
+ update_clone_start_failure ,
1802
+ update_clone_task_finished ,
1803
+ suc );
1804
+
1805
+ /*
1806
+ * We saved the output and put it out all at once now.
1807
+ * That means:
1808
+ * - the listener does not have to interleave their (checkout)
1809
+ * work with our fetching. The writes involved in a
1810
+ * checkout involve more straightforward sequential I/O.
1811
+ * - the listener can avoid doing any work if fetching failed.
1812
+ */
1813
+ if (suc -> quickstop )
1814
+ return 1 ;
1815
+
1816
+ for (i = 0 ; i < suc -> update_clone_nr ; i ++ )
1817
+ update_submodule (& suc -> update_clone [i ]);
1818
+
1819
+ return 0 ;
1820
+ }
1821
+
1717
1822
static int update_clone (int argc , const char * * argv , const char * prefix )
1718
1823
{
1719
1824
const char * update = NULL ;
1720
- int max_jobs = 1 ;
1721
- struct string_list_item * item ;
1722
1825
struct pathspec pathspec ;
1723
1826
struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT ;
1724
1827
@@ -1740,7 +1843,7 @@ static int update_clone(int argc, const char **argv, const char *prefix)
1740
1843
OPT_STRING (0 , "depth" , & suc .depth , "<depth>" ,
1741
1844
N_ ("Create a shallow clone truncated to the "
1742
1845
"specified number of revisions" )),
1743
- OPT_INTEGER ('j' , "jobs" , & max_jobs ,
1846
+ OPT_INTEGER ('j' , "jobs" , & suc . max_jobs ,
1744
1847
N_ ("parallel jobs" )),
1745
1848
OPT_BOOL (0 , "recommend-shallow" , & suc .recommend_shallow ,
1746
1849
N_ ("whether the initial clone should follow the shallow recommendation" )),
@@ -1756,8 +1859,8 @@ static int update_clone(int argc, const char **argv, const char *prefix)
1756
1859
};
1757
1860
suc .prefix = prefix ;
1758
1861
1759
- update_clone_config_from_gitmodules (& max_jobs );
1760
- git_config (git_update_clone_config , & max_jobs );
1862
+ update_clone_config_from_gitmodules (& suc . max_jobs );
1863
+ git_config (git_update_clone_config , & suc . max_jobs );
1761
1864
1762
1865
argc = parse_options (argc , argv , prefix , module_update_clone_options ,
1763
1866
git_submodule_helper_usage , 0 );
@@ -1772,27 +1875,7 @@ static int update_clone(int argc, const char **argv, const char *prefix)
1772
1875
if (pathspec .nr )
1773
1876
suc .warn_if_uninitialized = 1 ;
1774
1877
1775
- run_processes_parallel (max_jobs ,
1776
- update_clone_get_next_task ,
1777
- update_clone_start_failure ,
1778
- update_clone_task_finished ,
1779
- & suc );
1780
-
1781
- /*
1782
- * We saved the output and put it out all at once now.
1783
- * That means:
1784
- * - the listener does not have to interleave their (checkout)
1785
- * work with our fetching. The writes involved in a
1786
- * checkout involve more straightforward sequential I/O.
1787
- * - the listener can avoid doing any work if fetching failed.
1788
- */
1789
- if (suc .quickstop )
1790
- return 1 ;
1791
-
1792
- for_each_string_list_item (item , & suc .projectlines )
1793
- fprintf (stdout , "%s" , item -> string );
1794
-
1795
- return 0 ;
1878
+ return update_submodules (& suc );
1796
1879
}
1797
1880
1798
1881
static int resolve_relative_path (int argc , const char * * argv , const char * prefix )
@@ -1938,6 +2021,45 @@ static int push_check(int argc, const char **argv, const char *prefix)
1938
2021
return 0 ;
1939
2022
}
1940
2023
2024
+ static int ensure_core_worktree (int argc , const char * * argv , const char * prefix )
2025
+ {
2026
+ const struct submodule * sub ;
2027
+ const char * path ;
2028
+ char * cw ;
2029
+ struct repository subrepo ;
2030
+
2031
+ if (argc != 2 )
2032
+ BUG ("submodule--helper connect-gitdir-workingtree <name> <path>" );
2033
+
2034
+ path = argv [1 ];
2035
+
2036
+ sub = submodule_from_path (the_repository , & null_oid , path );
2037
+ if (!sub )
2038
+ BUG ("We could get the submodule handle before?" );
2039
+
2040
+ if (repo_submodule_init (& subrepo , the_repository , path ))
2041
+ die (_ ("could not get a repository handle for submodule '%s'" ), path );
2042
+
2043
+ if (!repo_config_get_string (& subrepo , "core.worktree" , & cw )) {
2044
+ char * cfg_file , * abs_path ;
2045
+ const char * rel_path ;
2046
+ struct strbuf sb = STRBUF_INIT ;
2047
+
2048
+ cfg_file = repo_git_path (& subrepo , "config" );
2049
+
2050
+ abs_path = absolute_pathdup (path );
2051
+ rel_path = relative_path (abs_path , subrepo .gitdir , & sb );
2052
+
2053
+ git_config_set_in_file (cfg_file , "core.worktree" , rel_path );
2054
+
2055
+ free (cfg_file );
2056
+ free (abs_path );
2057
+ strbuf_release (& sb );
2058
+ }
2059
+
2060
+ return 0 ;
2061
+ }
2062
+
1941
2063
static int absorb_git_dirs (int argc , const char * * argv , const char * prefix )
1942
2064
{
1943
2065
int i ;
@@ -2015,7 +2137,9 @@ static struct cmd_struct commands[] = {
2015
2137
{"list" , module_list , 0 },
2016
2138
{"name" , module_name , 0 },
2017
2139
{"clone" , module_clone , 0 },
2140
+ {"update-module-mode" , module_update_module_mode , 0 },
2018
2141
{"update-clone" , update_clone , 0 },
2142
+ {"ensure-core-worktree" , ensure_core_worktree , 0 },
2019
2143
{"relative-path" , resolve_relative_path , 0 },
2020
2144
{"resolve-relative-url" , resolve_relative_url , 0 },
2021
2145
{"resolve-relative-url-test" , resolve_relative_url_test , 0 },
0 commit comments