1414#include "blob.h"
1515#include "thread-utils.h"
1616#include "quote.h"
17+ #include "worktree.h"
1718
1819static int config_fetch_recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND ;
1920static int parallel_jobs = 1 ;
@@ -1296,30 +1297,6 @@ int merge_submodule(unsigned char result[20], const char *path,
12961297 return 0 ;
12971298}
12981299
1299- /* Update gitfile and core.worktree setting to connect work tree and git dir */
1300- void connect_work_tree_and_git_dir (const char * work_tree , const char * git_dir )
1301- {
1302- struct strbuf file_name = STRBUF_INIT ;
1303- struct strbuf rel_path = STRBUF_INIT ;
1304- const char * real_work_tree = xstrdup (real_path (work_tree ));
1305-
1306- /* Update gitfile */
1307- strbuf_addf (& file_name , "%s/.git" , work_tree );
1308- write_file (file_name .buf , "gitdir: %s" ,
1309- relative_path (git_dir , real_work_tree , & rel_path ));
1310-
1311- /* Update core.worktree setting */
1312- strbuf_reset (& file_name );
1313- strbuf_addf (& file_name , "%s/config" , git_dir );
1314- git_config_set_in_file (file_name .buf , "core.worktree" ,
1315- relative_path (real_work_tree , git_dir ,
1316- & rel_path ));
1317-
1318- strbuf_release (& file_name );
1319- strbuf_release (& rel_path );
1320- free ((void * )real_work_tree );
1321- }
1322-
13231300int parallel_submodules (void )
13241301{
13251302 return parallel_jobs ;
@@ -1335,3 +1312,105 @@ void prepare_submodule_repo_env(struct argv_array *out)
13351312 }
13361313 argv_array_push (out , "GIT_DIR=.git" );
13371314}
1315+
1316+ /*
1317+ * Embeds a single submodules git directory into the superprojects git dir,
1318+ * non recursively.
1319+ */
1320+ static void relocate_single_git_dir_into_superproject (const char * prefix ,
1321+ const char * path )
1322+ {
1323+ char * old_git_dir = NULL , * real_old_git_dir = NULL , * real_new_git_dir = NULL ;
1324+ const char * new_git_dir ;
1325+ const struct submodule * sub ;
1326+
1327+ if (submodule_uses_worktrees (path ))
1328+ die (_ ("relocate_gitdir for submodule '%s' with "
1329+ "more than one worktree not supported" ), path );
1330+
1331+ old_git_dir = xstrfmt ("%s/.git" , path );
1332+ if (read_gitfile (old_git_dir ))
1333+ /* If it is an actual gitfile, it doesn't need migration. */
1334+ return ;
1335+
1336+ real_old_git_dir = xstrdup (real_path (old_git_dir ));
1337+
1338+ sub = submodule_from_path (null_sha1 , path );
1339+ if (!sub )
1340+ die (_ ("could not lookup name for submodule '%s'" ), path );
1341+
1342+ new_git_dir = git_path ("modules/%s" , sub -> name );
1343+ if (safe_create_leading_directories_const (new_git_dir ) < 0 )
1344+ die (_ ("could not create directory '%s'" ), new_git_dir );
1345+ real_new_git_dir = xstrdup (real_path (new_git_dir ));
1346+
1347+ if (!prefix )
1348+ prefix = get_super_prefix ();
1349+
1350+ fprintf (stderr , _ ("Migrating git directory of '%s%s' from\n'%s' to\n'%s'\n" ),
1351+ prefix ? prefix : "" , path ,
1352+ real_old_git_dir , real_new_git_dir );
1353+
1354+ relocate_gitdir (path , real_old_git_dir , real_new_git_dir );
1355+
1356+ free (old_git_dir );
1357+ free (real_old_git_dir );
1358+ free (real_new_git_dir );
1359+ }
1360+
1361+ /*
1362+ * Migrate the git directory of the submodule given by path from
1363+ * having its git directory within the working tree to the git dir nested
1364+ * in its superprojects git dir under modules/.
1365+ */
1366+ void absorb_git_dir_into_superproject (const char * prefix ,
1367+ const char * path ,
1368+ unsigned flags )
1369+ {
1370+ const char * sub_git_dir , * v ;
1371+ char * real_sub_git_dir = NULL , * real_common_git_dir = NULL ;
1372+ struct strbuf gitdir = STRBUF_INIT ;
1373+
1374+ strbuf_addf (& gitdir , "%s/.git" , path );
1375+ sub_git_dir = resolve_gitdir (gitdir .buf );
1376+
1377+ /* Not populated? */
1378+ if (!sub_git_dir )
1379+ goto out ;
1380+
1381+ /* Is it already absorbed into the superprojects git dir? */
1382+ real_sub_git_dir = xstrdup (real_path (sub_git_dir ));
1383+ real_common_git_dir = xstrdup (real_path (get_git_common_dir ()));
1384+ if (!skip_prefix (real_sub_git_dir , real_common_git_dir , & v ))
1385+ relocate_single_git_dir_into_superproject (prefix , path );
1386+
1387+ if (flags & ABSORB_GITDIR_RECURSE_SUBMODULES ) {
1388+ struct child_process cp = CHILD_PROCESS_INIT ;
1389+ struct strbuf sb = STRBUF_INIT ;
1390+
1391+ if (flags & ~ABSORB_GITDIR_RECURSE_SUBMODULES )
1392+ die ("BUG: we don't know how to pass the flags down?" );
1393+
1394+ if (get_super_prefix ())
1395+ strbuf_addstr (& sb , get_super_prefix ());
1396+ strbuf_addstr (& sb , path );
1397+ strbuf_addch (& sb , '/' );
1398+
1399+ cp .dir = path ;
1400+ cp .git_cmd = 1 ;
1401+ cp .no_stdin = 1 ;
1402+ argv_array_pushl (& cp .args , "--super-prefix" , sb .buf ,
1403+ "submodule--helper" ,
1404+ "absorb-git-dirs" , NULL );
1405+ prepare_submodule_repo_env (& cp .env_array );
1406+ if (run_command (& cp ))
1407+ die (_ ("could not recurse into submodule '%s'" ), path );
1408+
1409+ strbuf_release (& sb );
1410+ }
1411+
1412+ out :
1413+ strbuf_release (& gitdir );
1414+ free (real_sub_git_dir );
1415+ free (real_common_git_dir );
1416+ }
0 commit comments