init: reset cached config when entering new repo

After we copy the templates into place, we re-read the config in case we copied in a default config file. But since git_config() is backed by a cache these days, it's possible that the call will not actually touch the filesystem at all; we need to tell it that something has changed behind the scenes. Note that we also need to reset the shared_repository config. At first glance, it seems like this should probably just be folded into git_config_clear(). But unfortunately that is not quite right. The shared repository value may come from config, _or_ it may have been set manually. So only the caller who knows whether or not they set it is the one who can clear it (and indeed, if you _do_ put it into git_config_clear(), then many tests fail, as we have to clear the config cache any time we set a new config variable). There are three tests here. The first two actually pass already, though it's largely luck: they just don't happen to actually read any config before we enter the new repo. But the third one does fail without this patch; we look at core.sharedrepository while creating the directory, but need to make sure the value from the template config overrides it. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Sep 12, 2016 at 20:24 UTC 4543926ba8f8ec596dd4e45f206f4fbc29350567
4 files changed +50
builtin/init-db.c
+6
@@ -195,8 +195,14 @@ static int create_default_files(const char *template_path)
195 * First copy the templates -- we might have the default
196 * config file there, in which case we would want to read
197 * from it after installing.
198 + *
199 + * Before reading that config, we also need to clear out any cached
200 + * values (since we've just potentially changed what's available on
201 + * disk).
202 */
203 copy_templates(template_path);
204 + git_config_clear();
205 + reset_shared_repository();
206 git_config(git_default_config, NULL);
207
208 /*
cache.h
+7
@@ -669,8 +669,15 @@ extern size_t delta_base_cache_limit;
669 extern unsigned long big_file_threshold;
670 extern unsigned long pack_size_limit_cfg;
671
672 +/*
673 + * Accessors for the core.sharedrepository config which lazy-load the value
674 + * from the config (if not already set). The "reset" function can be
675 + * used to unset "set" or cached value, meaning that the value will be loaded
676 + * fresh from the config file on the next call to get_shared_repository().
677 + */
678 void set_shared_repository(int value);
679 int get_shared_repository(void);
680 +void reset_shared_repository(void);
681
682 /*
683 * Do replace refs need to be checked this run? This variable is
environment.c
+5
@@ -350,3 +350,8 @@ int get_shared_repository(void)
350 }
351 return the_shared_repository;
352 }
353 +
354 +void reset_shared_repository(void)
355 +{
356 + need_shared_repository_from_config = 1;
357 +}
t/t1301-shared-repo.sh
+32
@@ -181,4 +181,36 @@ test_expect_success POSIXPERM 'remote init does not use config from cwd' '
181 test_cmp expect actual
182 '
183
184 +test_expect_success POSIXPERM 're-init respects core.sharedrepository (local)' '
185 + git config core.sharedrepository 0666 &&
186 + umask 0022 &&
187 + echo whatever >templates/foo &&
188 + git init --template=templates &&
189 + echo "-rw-rw-rw-" >expect &&
190 + modebits .git/foo >actual &&
191 + test_cmp expect actual
192 +'
193 +
194 +test_expect_success POSIXPERM 're-init respects core.sharedrepository (remote)' '
195 + rm -rf child.git &&
196 + umask 0022 &&
197 + git init --bare --shared=0666 child.git &&
198 + test_path_is_missing child.git/foo &&
199 + git init --bare --template=../templates child.git &&
200 + echo "-rw-rw-rw-" >expect &&
201 + modebits child.git/foo >actual &&
202 + test_cmp expect actual
203 +'
204 +
205 +test_expect_success POSIXPERM 'template can set core.sharedrepository' '
206 + rm -rf child.git &&
207 + umask 0022 &&
208 + git config core.sharedrepository 0666 &&
209 + cp .git/config templates/config &&
210 + git init --bare --template=../templates child.git &&
211 + echo "-rw-rw-rw-" >expect &&
212 + modebits child.git/HEAD >actual &&
213 + test_cmp expect actual
214 +'
215 +
216 test_done