14
#include "blob.h"
15
#include "thread-utils.h"
16
#include "quote.h"
17
+#include "worktree.h"
18
19
static int config_fetch_recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND;
20
static int parallel_jobs = 1;
1238
}
1239
argv_array_push(out, "GIT_DIR=.git");
1240
}
1241
+
1242
+/*
1243
+ * Embeds a single submodules git directory into the superprojects git dir,
1244
+ * non recursively.
1245
+ */
1246
+static void relocate_single_git_dir_into_superproject(const char *prefix,
1247
+ const char *path)
1248
+{
1249
+ char *old_git_dir = NULL, *real_old_git_dir = NULL, *real_new_git_dir = NULL;
1250
+ const char *new_git_dir;
1251
+ const struct submodule *sub;
1252
+
1253
+ if (submodule_uses_worktrees(path))
1254
+ die(_("relocate_gitdir for submodule '%s' with "
1255
+ "more than one worktree not supported"), path);
1256
+
1257
+ old_git_dir = xstrfmt("%s/.git", path);
1258
+ if (read_gitfile(old_git_dir))
1259
+ /* If it is an actual gitfile, it doesn't need migration. */
1260
+ return;
1261
+
1262
+ real_old_git_dir = xstrdup(real_path(old_git_dir));
1263
+
1264
+ sub = submodule_from_path(null_sha1, path);
1265
+ if (!sub)
1266
+ die(_("could not lookup name for submodule '%s'"), path);
1267
+
1268
+ new_git_dir = git_path("modules/%s", sub->name);
1269
+ if (safe_create_leading_directories_const(new_git_dir) < 0)
1270
+ die(_("could not create directory '%s'"), new_git_dir);
1271
+ real_new_git_dir = xstrdup(real_path(new_git_dir));
1272
+
1273
+ if (!prefix)
1274
+ prefix = get_super_prefix();
1275
+
1276
+ fprintf(stderr, _("Migrating git directory of '%s%s' from\n'%s' to\n'%s'\n"),
1277
+ prefix ? prefix : "", path,
1278
+ real_old_git_dir, real_new_git_dir);
1279
+
1280
+ relocate_gitdir(path, real_old_git_dir, real_new_git_dir);
1281
+
1282
+ free(old_git_dir);
1283
+ free(real_old_git_dir);
1284
+ free(real_new_git_dir);
1285
+}
1286
+
1287
+/*
1288
+ * Migrate the git directory of the submodule given by path from
1289
+ * having its git directory within the working tree to the git dir nested
1290
+ * in its superprojects git dir under modules/.
1291
+ */
1292
+void absorb_git_dir_into_superproject(const char *prefix,
1293
+ const char *path,
1294
+ unsigned flags)
1295
+{
1296
+ const char *sub_git_dir, *v;
1297
+ char *real_sub_git_dir = NULL, *real_common_git_dir = NULL;
1298
+ struct strbuf gitdir = STRBUF_INIT;
1299
+
1300
+ strbuf_addf(&gitdir, "%s/.git", path);
1301
+ sub_git_dir = resolve_gitdir(gitdir.buf);
1302
+
1303
+ /* Not populated? */
1304
+ if (!sub_git_dir)
1305
+ goto out;
1306
+
1307
+ /* Is it already absorbed into the superprojects git dir? */
1308
+ real_sub_git_dir = xstrdup(real_path(sub_git_dir));
1309
+ real_common_git_dir = xstrdup(real_path(get_git_common_dir()));
1310
+ if (!skip_prefix(real_sub_git_dir, real_common_git_dir, &v))
1311
+ relocate_single_git_dir_into_superproject(prefix, path);
1312
+
1313
+ if (flags & ABSORB_GITDIR_RECURSE_SUBMODULES) {
1314
+ struct child_process cp = CHILD_PROCESS_INIT;
1315
+ struct strbuf sb = STRBUF_INIT;
1316
+
1317
+ if (flags & ~ABSORB_GITDIR_RECURSE_SUBMODULES)
1318
+ die("BUG: we don't know how to pass the flags down?");
1319
+
1320
+ if (get_super_prefix())
1321
+ strbuf_addstr(&sb, get_super_prefix());
1322
+ strbuf_addstr(&sb, path);
1323
+ strbuf_addch(&sb, '/');
1324
+
1325
+ cp.dir = path;
1326
+ cp.git_cmd = 1;
1327
+ cp.no_stdin = 1;
1328
+ argv_array_pushl(&cp.args, "--super-prefix", sb.buf,
1329
+ "submodule--helper",
1330
+ "absorb-git-dirs", NULL);
1331
+ prepare_submodule_repo_env(&cp.env_array);
1332
+ if (run_command(&cp))
1333
+ die(_("could not recurse into submodule '%s'"), path);
1334
+
1335
+ strbuf_release(&sb);
1336
+ }
1337
+
1338
+out:
1339
+ strbuf_release(&gitdir);
1340
+ free(real_sub_git_dir);
1341
+ free(real_common_git_dir);
1342
+}