submodule: migrate get_next_submodule to use repository structs
We used to recurse into submodules, even if they were broken having only an objects directory. The child process executed in the submodule would fail though if the submodule was broken. This is tested via "fetching submodule into a broken repository" in t5526. This patch tightens the check upfront, such that we do not need to spawn a child process to find out if the submodule is broken. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Stefan Beller committed
Nov 28, 2018 at 16:27 UTC
26f80ccfc15bb1e591b634173bdb7092da33da12
1 file changed
+44
-12
submodule.c
+44
-12
@@ -1253,6 +1253,30 @@ static int get_fetch_recurse_config(const struct submodule *submodule,
1253
return spf->default_option;
1254
}
1255
1256
+static struct repository *get_submodule_repo_for(struct repository *r,
1257
+ const struct submodule *sub)
1258
+{
1259
+ struct repository *ret = xmalloc(sizeof(*ret));
1260
+
1261
+ if (repo_submodule_init(ret, r, sub)) {
1262
+ /*
1263
+ * No entry in .gitmodules? Technically not a submodule,
1264
+ * but historically we supported repositories that happen to be
1265
+ * in-place where a gitlink is. Keep supporting them.
1266
+ */
1267
+ struct strbuf gitdir = STRBUF_INIT;
1268
+ strbuf_repo_worktree_path(&gitdir, r, "%s/.git", sub->path);
1269
+ if (repo_init(ret, gitdir.buf, NULL)) {
1270
+ strbuf_release(&gitdir);
1271
+ free(ret);
1272
+ return NULL;
1273
+ }
1274
+ strbuf_release(&gitdir);
1275
+ }
1276
+
1277
+ return ret;
1278
+}
1279
+
1280
static int get_next_submodule(struct child_process *cp,
1281
struct strbuf *err, void *data, void **task_cb)
1282
{
@@ -1260,12 +1284,11 @@ static int get_next_submodule(struct child_process *cp,
1284
struct submodule_parallel_fetch *spf = data;
1285
1286
for (; spf->count < spf->r->index->cache_nr; spf->count++) {
1263
- struct strbuf submodule_path = STRBUF_INIT;
1264
- struct strbuf submodule_git_dir = STRBUF_INIT;
1287
struct strbuf submodule_prefix = STRBUF_INIT;
1288
const struct cache_entry *ce = spf->r->index->cache[spf->count];
1267
- const char *git_dir, *default_argv;
1289
+ const char *default_argv;
1290
const struct submodule *submodule;
1291
+ struct repository *repo;
1292
struct submodule default_submodule = SUBMODULE_INIT;
1293
1294
if (!S_ISGITLINK(ce->ce_mode))
@@ -1300,15 +1323,11 @@ static int get_next_submodule(struct child_process *cp,
1323
continue;
1324
}
1325
1303
- strbuf_repo_worktree_path(&submodule_path, spf->r, "%s", ce->name);
1304
- strbuf_addf(&submodule_git_dir, "%s/.git", submodule_path.buf);
1326
strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, ce->name);
1306
- git_dir = read_gitfile(submodule_git_dir.buf);
1307
- if (!git_dir)
1308
- git_dir = submodule_git_dir.buf;
1309
- if (is_directory(git_dir)) {
1327
+ repo = get_submodule_repo_for(spf->r, submodule);
1328
+ if (repo) {
1329
child_process_init(cp);
1311
- cp->dir = strbuf_detach(&submodule_path, NULL);
1330
+ cp->dir = xstrdup(repo->worktree);
1331
prepare_submodule_repo_env(&cp->env_array);
1332
cp->git_cmd = 1;
1333
if (!spf->quiet)
@@ -1319,10 +1338,23 @@ static int get_next_submodule(struct child_process *cp,
1338
argv_array_push(&cp->args, default_argv);
1339
argv_array_push(&cp->args, "--submodule-prefix");
1340
argv_array_push(&cp->args, submodule_prefix.buf);
1341
+
1342
+ repo_clear(repo);
1343
+ free(repo);
1344
ret = 1;
1345
+ } else {
1346
+ /*
1347
+ * An empty directory is normal,
1348
+ * the submodule is not initialized
1349
+ */
1350
+ if (S_ISGITLINK(ce->ce_mode) &&
1351
+ !is_empty_dir(ce->name)) {
1352
+ spf->result = 1;
1353
+ strbuf_addf(err,
1354
+ _("Could not access submodule '%s'"),
1355
+ ce->name);
1356
+ }
1357
}
1324
- strbuf_release(&submodule_path);
1325
- strbuf_release(&submodule_git_dir);
1358
strbuf_release(&submodule_prefix);
1359
if (ret) {
1360
spf->count++;