Glen Choo <chooglen@xxxxxxxxxx> writes: > Junio C Hamano <gitster@xxxxxxxxx> writes: > >>> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c >>> index bef9ab22d4..f53808d995 100644 >>> --- a/builtin/submodule--helper.c >>> +++ b/builtin/submodule--helper.c >>> @@ -2672,6 +2677,11 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) >>> &update_data.update_strategy); >>> >>> free(prefixed_path); >>> + /* >>> + * This entry point is always called from a submodule, so this is a >>> + * good place to set a hint that this repo is a submodule. >>> + */ >>> + git_config_set("submodule.hasSuperproject", "true"); >>> return update_submodule2(&update_data); >>> } >> >> That matched my tentative resolution I made last night, but what do >> you think about this part of the test added by the patch? >> >> diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh >> index 11cccbb333..ec2397fc69 100755 >> --- a/t/t7406-submodule-update.sh >> +++ b/t/t7406-submodule-update.sh >> @@ -1061,4 +1061,12 @@ test_expect_success 'submodule update --quiet passes quietness to fetch with a s >> ) >> ' >> >> +test_expect_success 'submodule update adds submodule.hasSuperproject to older repos' ' >> + (cd super && >> + test_unconfig submodule.hasSuperproject && >> + git submodule update && >> + test_cmp_config -C submodule true --type=bool submodule.hasSuperproject >> + ) >> +' >> + >> test_done >> >> We go to "super", make sure that superproject does not have >> submodule.hasSuperproject set, run "git submodule update", and see >> if the configuration file in "submodule" subdirectory has the >> variable set. It does not clear the variable from the submodule >> before starting, so the variable given to the submodule when it was >> cloned would be there, even if "git submodule update" failed to set >> it. >> >> I am wondering if it should do something like the attached instead. >> >> We >> >> * clear the variable from "super" and "super/submodule" >> repositories; >> >> * run "git submodule update"; >> >> * ensure that "git submodule update" did not touch "super/.git/config"; >> >> * ensure that "git submodule update" added the variable to >> "super/submodule/.git/config". >> >> Clearing the variable from "super" is technically wrong because the >> repository is set up as a submodule of "recursivesuper" and if we >> had further tests, we should restore it in "super", but the point is >> that we are makng sure "git submodule update" sets the variable in >> the configuration file of the submodule, and not in the superproject's. > > Yes, the test you've described is closer to what I thought the original > test was trying to do. Seeing this test pass gave me a false sense of > confidence hm.. Correction, seeing the _original_ test pass gave me false sense of confidence. >> With the conflict resolution above, this "corrected" test fails and >> shows that superproject's configuration file is updated after "git >> submodule update". >> >> This series alone, without your topic, this "corrected" test fails, >> and that is where my "are we sure we are mucking with the >> configuration file in the submodule"? comes from. > - Set the config in the submodule even though we are running from the > superproject (this is possible, ensure_core_worktree() does this). If it helps, I was able to do this up by copying ensure_core_worktree(), and this passes the amended test. ----- >8 --------- >8 --------- >8 --------- >8 --------- >8 ---- diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 4d02dd05ca..3bb7a65762 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1838,11 +1838,6 @@ static int clone_submodule(struct module_clone_data *clone_data) git_config_set_in_file(p, "submodule.alternateErrorStrategy", error_strategy); - /* - * Teach the submodule that it's a submodule. - */ - git_config_set_in_file(p, "submodule.hasSuperproject", "true"); - free(sm_alternate); free(error_strategy); @@ -2560,6 +2555,20 @@ static int update_clone(int argc, const char **argv, const char *prefix) return update_submodules(&suc); } +static void set_hassuperproject(const char *sm_path) +{ + struct repository subrepo; + char *cfg_file; + + if (repo_submodule_init(&subrepo, the_repository, sm_path, null_oid())) + die(_("could not get a repository handle for submodule '%s'"), sm_path); + + cfg_file = repo_git_path(&subrepo, "config"); + git_config_set_in_file(cfg_file, "submodule.hasSuperproject", "true"); + + free(cfg_file); +} + static int run_update_procedure(int argc, const char **argv, const char *prefix) { int force = 0, quiet = 0, nofetch = 0, just_cloned = 0; @@ -2622,10 +2631,9 @@ static int run_update_procedure(int argc, const char **argv, const char *prefix) free(prefixed_path); /* - * This entry point is always called from a submodule, so this is a - * good place to set a hint that this repo is a submodule. + * Teach the submodule that it's a submodule. */ - git_config_set("submodule.hasSuperproject", "true"); + set_hassuperproject(update_data.sm_path); if (!oideq(&update_data.oid, &update_data.suboid) || update_data.force) return do_run_update_procedure(&update_data);