Skip to content

Commit f2d4899

Browse files
stefanbellergitster
authored andcommitted
submodule.c: submodule_move_head works with broken submodules
Early on in submodule_move_head just after the check if the submodule is initialized, we need to check if the submodule is populated correctly. If the submodule is initialized but doesn't look like it is populated, this is a red flag and can indicate multiple sorts of failures: (1) The submodule may be recorded at an object name, that is missing. (2) The submodule '.git' file link may be broken and it is not pointing at a repository. In both cases we want to complain to the user in the non-forced mode, and in the forced mode ignoring the old state and just moving the submodule into its new state with a fixed '.git' file link. Signed-off-by: Stefan Beller <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 823bab0 commit f2d4899

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

submodule.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,10 +1332,24 @@ int submodule_move_head(const char *path,
13321332
int ret = 0;
13331333
struct child_process cp = CHILD_PROCESS_INIT;
13341334
const struct submodule *sub;
1335+
int *error_code_ptr, error_code;
13351336

13361337
if (!is_submodule_initialized(path))
13371338
return 0;
13381339

1340+
if (flags & SUBMODULE_MOVE_HEAD_FORCE)
1341+
/*
1342+
* Pass non NULL pointer to is_submodule_populated_gently
1343+
* to prevent die()-ing. We'll use connect_work_tree_and_git_dir
1344+
* to fixup the submodule in the force case later.
1345+
*/
1346+
error_code_ptr = &error_code;
1347+
else
1348+
error_code_ptr = NULL;
1349+
1350+
if (old && !is_submodule_populated_gently(path, error_code_ptr))
1351+
return 0;
1352+
13391353
sub = submodule_from_path(null_sha1, path);
13401354

13411355
if (!sub)
@@ -1353,15 +1367,21 @@ int submodule_move_head(const char *path,
13531367
absorb_git_dir_into_superproject("", path,
13541368
ABSORB_GITDIR_RECURSE_SUBMODULES);
13551369
} else {
1356-
struct strbuf sb = STRBUF_INIT;
1357-
strbuf_addf(&sb, "%s/modules/%s",
1370+
char *gitdir = xstrfmt("%s/modules/%s",
13581371
get_git_common_dir(), sub->name);
1359-
connect_work_tree_and_git_dir(path, sb.buf);
1360-
strbuf_release(&sb);
1372+
connect_work_tree_and_git_dir(path, gitdir);
1373+
free(gitdir);
13611374

13621375
/* make sure the index is clean as well */
13631376
submodule_reset_index(path);
13641377
}
1378+
1379+
if (old && (flags & SUBMODULE_MOVE_HEAD_FORCE)) {
1380+
char *gitdir = xstrfmt("%s/modules/%s",
1381+
get_git_common_dir(), sub->name);
1382+
connect_work_tree_and_git_dir(path, gitdir);
1383+
free(gitdir);
1384+
}
13651385
}
13661386

13671387
prepare_submodule_repo_env_no_git_dir(&cp.env_array);

t/lib-submodule-update.sh

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,14 +1213,31 @@ test_submodule_forced_switch_recursing () {
12131213
)
12141214
'
12151215
# Updating a submodule from an invalid sha1 updates
1216-
test_expect_success "$command: modified submodule does not update submodule work tree from invalid commit" '
1216+
test_expect_success "$command: modified submodule does update submodule work tree from invalid commit" '
12171217
prolog &&
12181218
reset_work_tree_to_interested invalid_sub1 &&
12191219
(
12201220
cd submodule_update &&
12211221
git branch -t valid_sub1 origin/valid_sub1 &&
1222-
test_must_fail $command valid_sub1 &&
1223-
test_superproject_content origin/invalid_sub1
1222+
$command valid_sub1 &&
1223+
test_superproject_content origin/valid_sub1 &&
1224+
test_submodule_content sub1 origin/valid_sub1
1225+
)
1226+
'
1227+
1228+
# Old versions of Git were buggy writing the .git link file
1229+
# (e.g. before f8eaa0ba98b and then moving the superproject repo
1230+
# whose submodules contained absolute paths)
1231+
test_expect_success "$command: updating submodules fixes .git links" '
1232+
prolog &&
1233+
reset_work_tree_to_interested add_sub1 &&
1234+
(
1235+
cd submodule_update &&
1236+
git branch -t modify_sub1 origin/modify_sub1 &&
1237+
echo "gitdir: bogus/path" >sub1/.git &&
1238+
$command modify_sub1 &&
1239+
test_superproject_content origin/modify_sub1 &&
1240+
test_submodule_content sub1 origin/modify_sub1
12241241
)
12251242
'
12261243
}

0 commit comments

Comments
 (0)