@@ -1231,8 +1231,14 @@ struct submodule_parallel_fetch {
12311231 int result ;
12321232
12331233 struct string_list changed_submodule_names ;
1234+
1235+ /* Pending fetches by OIDs */
1236+ struct fetch_task * * oid_fetch_tasks ;
1237+ int oid_fetch_tasks_nr , oid_fetch_tasks_alloc ;
12341238};
1235- #define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
1239+ #define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, \
1240+ STRING_LIST_INIT_DUP, \
1241+ NULL, 0, 0}
12361242
12371243static int get_fetch_recurse_config (const struct submodule * submodule ,
12381244 struct submodule_parallel_fetch * spf )
@@ -1259,6 +1265,76 @@ static int get_fetch_recurse_config(const struct submodule *submodule,
12591265 return spf -> default_option ;
12601266}
12611267
1268+ /*
1269+ * Fetch in progress (if callback data) or
1270+ * pending (if in oid_fetch_tasks in struct submodule_parallel_fetch)
1271+ */
1272+ struct fetch_task {
1273+ struct repository * repo ;
1274+ const struct submodule * sub ;
1275+ unsigned free_sub : 1 ; /* Do we need to free the submodule? */
1276+
1277+ struct oid_array * commits ; /* Ensure these commits are fetched */
1278+ };
1279+
1280+ /**
1281+ * When a submodule is not defined in .gitmodules, we cannot access it
1282+ * via the regular submodule-config. Create a fake submodule, which we can
1283+ * work on.
1284+ */
1285+ static const struct submodule * get_non_gitmodules_submodule (const char * path )
1286+ {
1287+ struct submodule * ret = NULL ;
1288+ const char * name = default_name_or_path (path );
1289+
1290+ if (!name )
1291+ return NULL ;
1292+
1293+ ret = xmalloc (sizeof (* ret ));
1294+ memset (ret , 0 , sizeof (* ret ));
1295+ ret -> path = name ;
1296+ ret -> name = name ;
1297+
1298+ return (const struct submodule * ) ret ;
1299+ }
1300+
1301+ static struct fetch_task * fetch_task_create (struct repository * r ,
1302+ const char * path )
1303+ {
1304+ struct fetch_task * task = xmalloc (sizeof (* task ));
1305+ memset (task , 0 , sizeof (* task ));
1306+
1307+ task -> sub = submodule_from_path (r , & null_oid , path );
1308+ if (!task -> sub ) {
1309+ /*
1310+ * No entry in .gitmodules? Technically not a submodule,
1311+ * but historically we supported repositories that happen to be
1312+ * in-place where a gitlink is. Keep supporting them.
1313+ */
1314+ task -> sub = get_non_gitmodules_submodule (path );
1315+ if (!task -> sub ) {
1316+ free (task );
1317+ return NULL ;
1318+ }
1319+
1320+ task -> free_sub = 1 ;
1321+ }
1322+
1323+ return task ;
1324+ }
1325+
1326+ static void fetch_task_release (struct fetch_task * p )
1327+ {
1328+ if (p -> free_sub )
1329+ free ((void * )p -> sub );
1330+ p -> free_sub = 0 ;
1331+ p -> sub = NULL ;
1332+
1333+ if (p -> repo )
1334+ repo_clear (p -> repo );
1335+ FREE_AND_NULL (p -> repo );
1336+ }
1337+
12621338static struct repository * get_submodule_repo_for (struct repository * r ,
12631339 const struct submodule * sub )
12641340{
@@ -1286,39 +1362,29 @@ static struct repository *get_submodule_repo_for(struct repository *r,
12861362static int get_next_submodule (struct child_process * cp ,
12871363 struct strbuf * err , void * data , void * * task_cb )
12881364{
1289- int ret = 0 ;
12901365 struct submodule_parallel_fetch * spf = data ;
12911366
12921367 for (; spf -> count < spf -> r -> index -> cache_nr ; spf -> count ++ ) {
1293- struct strbuf submodule_prefix = STRBUF_INIT ;
12941368 const struct cache_entry * ce = spf -> r -> index -> cache [spf -> count ];
12951369 const char * default_argv ;
1296- const struct submodule * submodule ;
1297- struct repository * repo ;
1298- struct submodule default_submodule = SUBMODULE_INIT ;
1370+ struct fetch_task * task ;
12991371
13001372 if (!S_ISGITLINK (ce -> ce_mode ))
13011373 continue ;
13021374
1303- submodule = submodule_from_path (spf -> r , & null_oid , ce -> name );
1304- if (!submodule ) {
1305- const char * name = default_name_or_path (ce -> name );
1306- if (name ) {
1307- default_submodule .path = name ;
1308- default_submodule .name = name ;
1309- submodule = & default_submodule ;
1310- }
1311- }
1375+ task = fetch_task_create (spf -> r , ce -> name );
1376+ if (!task )
1377+ continue ;
13121378
1313- switch (get_fetch_recurse_config (submodule , spf ))
1379+ switch (get_fetch_recurse_config (task -> sub , spf ))
13141380 {
13151381 default :
13161382 case RECURSE_SUBMODULES_DEFAULT :
13171383 case RECURSE_SUBMODULES_ON_DEMAND :
1318- if (!submodule ||
1384+ if (!task -> sub ||
13191385 !string_list_lookup (
13201386 & spf -> changed_submodule_names ,
1321- submodule -> name ))
1387+ task -> sub -> name ))
13221388 continue ;
13231389 default_argv = "on-demand" ;
13241390 break ;
@@ -1329,11 +1395,11 @@ static int get_next_submodule(struct child_process *cp,
13291395 continue ;
13301396 }
13311397
1332- strbuf_addf ( & submodule_prefix , "%s%s/" , spf -> prefix , ce -> name );
1333- repo = get_submodule_repo_for ( spf -> r , submodule );
1334- if ( repo ) {
1398+ task -> repo = get_submodule_repo_for ( spf -> r , task -> sub );
1399+ if ( task -> repo ) {
1400+ struct strbuf submodule_prefix = STRBUF_INIT ;
13351401 child_process_init (cp );
1336- cp -> dir = xstrdup ( repo -> gitdir ) ;
1402+ cp -> dir = task -> repo -> gitdir ;
13371403 prepare_submodule_repo_env_in_gitdir (& cp -> env_array );
13381404 cp -> git_cmd = 1 ;
13391405 if (!spf -> quiet )
@@ -1343,12 +1409,22 @@ static int get_next_submodule(struct child_process *cp,
13431409 argv_array_pushv (& cp -> args , spf -> args .argv );
13441410 argv_array_push (& cp -> args , default_argv );
13451411 argv_array_push (& cp -> args , "--submodule-prefix" );
1412+
1413+ strbuf_addf (& submodule_prefix , "%s%s/" ,
1414+ spf -> prefix ,
1415+ task -> sub -> path );
13461416 argv_array_push (& cp -> args , submodule_prefix .buf );
13471417
1348- repo_clear (repo );
1349- free (repo );
1350- ret = 1 ;
1418+ spf -> count ++ ;
1419+ * task_cb = task ;
1420+
1421+ strbuf_release (& submodule_prefix );
1422+ return 1 ;
13511423 } else {
1424+
1425+ fetch_task_release (task );
1426+ free (task );
1427+
13521428 /*
13531429 * An empty directory is normal,
13541430 * the submodule is not initialized
@@ -1361,33 +1437,105 @@ static int get_next_submodule(struct child_process *cp,
13611437 ce -> name );
13621438 }
13631439 }
1440+ }
1441+
1442+ if (spf -> oid_fetch_tasks_nr ) {
1443+ struct fetch_task * task =
1444+ spf -> oid_fetch_tasks [spf -> oid_fetch_tasks_nr - 1 ];
1445+ struct strbuf submodule_prefix = STRBUF_INIT ;
1446+ spf -> oid_fetch_tasks_nr -- ;
1447+
1448+ strbuf_addf (& submodule_prefix , "%s%s/" ,
1449+ spf -> prefix , task -> sub -> path );
1450+
1451+ child_process_init (cp );
1452+ prepare_submodule_repo_env_in_gitdir (& cp -> env_array );
1453+ cp -> git_cmd = 1 ;
1454+ cp -> dir = task -> repo -> gitdir ;
1455+
1456+ argv_array_init (& cp -> args );
1457+ argv_array_pushv (& cp -> args , spf -> args .argv );
1458+ argv_array_push (& cp -> args , "on-demand" );
1459+ argv_array_push (& cp -> args , "--submodule-prefix" );
1460+ argv_array_push (& cp -> args , submodule_prefix .buf );
1461+
1462+ /* NEEDSWORK: have get_default_remote from submodule--helper */
1463+ argv_array_push (& cp -> args , "origin" );
1464+ oid_array_for_each_unique (task -> commits ,
1465+ append_oid_to_argv , & cp -> args );
1466+
1467+ * task_cb = task ;
13641468 strbuf_release (& submodule_prefix );
1365- if (ret ) {
1366- spf -> count ++ ;
1367- return 1 ;
1368- }
1469+ return 1 ;
13691470 }
1471+
13701472 return 0 ;
13711473}
13721474
13731475static int fetch_start_failure (struct strbuf * err ,
13741476 void * cb , void * task_cb )
13751477{
13761478 struct submodule_parallel_fetch * spf = cb ;
1479+ struct fetch_task * task = task_cb ;
13771480
13781481 spf -> result = 1 ;
13791482
1483+ fetch_task_release (task );
13801484 return 0 ;
13811485}
13821486
1487+ static int commit_missing_in_sub (const struct object_id * oid , void * data )
1488+ {
1489+ struct repository * subrepo = data ;
1490+
1491+ enum object_type type = oid_object_info (subrepo , oid , NULL );
1492+
1493+ return type != OBJ_COMMIT ;
1494+ }
1495+
13831496static int fetch_finish (int retvalue , struct strbuf * err ,
13841497 void * cb , void * task_cb )
13851498{
13861499 struct submodule_parallel_fetch * spf = cb ;
1500+ struct fetch_task * task = task_cb ;
1501+
1502+ struct string_list_item * it ;
1503+ struct oid_array * commits ;
13871504
13881505 if (retvalue )
13891506 spf -> result = 1 ;
13901507
1508+ if (!task || !task -> sub )
1509+ BUG ("callback cookie bogus" );
1510+
1511+ /* Is this the second time we process this submodule? */
1512+ if (task -> commits )
1513+ goto out ;
1514+
1515+ it = string_list_lookup (& spf -> changed_submodule_names , task -> sub -> name );
1516+ if (!it )
1517+ /* Could be an unchanged submodule, not contained in the list */
1518+ goto out ;
1519+
1520+ commits = it -> util ;
1521+ oid_array_filter (commits ,
1522+ commit_missing_in_sub ,
1523+ task -> repo );
1524+
1525+ /* Are there commits we want, but do not exist? */
1526+ if (commits -> nr ) {
1527+ task -> commits = commits ;
1528+ ALLOC_GROW (spf -> oid_fetch_tasks ,
1529+ spf -> oid_fetch_tasks_nr + 1 ,
1530+ spf -> oid_fetch_tasks_alloc );
1531+ spf -> oid_fetch_tasks [spf -> oid_fetch_tasks_nr ] = task ;
1532+ spf -> oid_fetch_tasks_nr ++ ;
1533+ return 0 ;
1534+ }
1535+
1536+ out :
1537+ fetch_task_release (task );
1538+
13911539 return 0 ;
13921540}
13931541
0 commit comments