setup: correctly reinitialize repository version
When reinitializing a repository, Git does not account for extensions other than `objectformat` and `refstorage` when determining the repository version. This can lead to a repository being downgraded to version 0 if extensions are set, causing Git future operations to fail. This patch teaches Git to check if other extensions are defined in the config to ensure that the repository version is set correctly. Signed-off-by: Caleb White <cdwhite3@pm.me> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Caleb White committed
Nov 29, 2024 at 22:22 UTC
d897f2c16da9ab9588d2015121449d5bc54c9736
2 files changed
+26
-12
setup.c
+23
-9
@@ -2204,8 +2204,8 @@ void initialize_repository_version(int hash_algo,
2204
enum ref_storage_format ref_storage_format,
2205
int reinit)
2206
{
2207
- char repo_version_string[10];
2208
- int repo_version = GIT_REPO_VERSION;
2207
+ struct strbuf repo_version = STRBUF_INIT;
2208
+ int target_version = GIT_REPO_VERSION;
2209
2210
/*
2211
* Note that we initialize the repository version to 1 when the ref
@@ -2216,12 +2216,7 @@ void initialize_repository_version(int hash_algo,
2216
*/
2217
if (hash_algo != GIT_HASH_SHA1 ||
2218
ref_storage_format != REF_STORAGE_FORMAT_FILES)
2219
- repo_version = GIT_REPO_VERSION_READ;
2220
-
2221
- /* This forces creation of new config file */
2222
- xsnprintf(repo_version_string, sizeof(repo_version_string),
2223
- "%d", repo_version);
2224
- git_config_set("core.repositoryformatversion", repo_version_string);
2219
+ target_version = GIT_REPO_VERSION_READ;
2220
2221
if (hash_algo != GIT_HASH_SHA1 && hash_algo != GIT_HASH_UNKNOWN)
2222
git_config_set("extensions.objectformat",
@@ -2234,6 +2229,25 @@ void initialize_repository_version(int hash_algo,
2229
ref_storage_format_to_name(ref_storage_format));
2230
else if (reinit)
2231
git_config_set_gently("extensions.refstorage", NULL);
2232
+
2233
+ if (reinit) {
2234
+ struct strbuf config = STRBUF_INIT;
2235
+ struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
2236
+
2237
+ strbuf_git_common_path(&config, the_repository, "config");
2238
+ read_repository_format(&repo_fmt, config.buf);
2239
+
2240
+ if (repo_fmt.v1_only_extensions.nr)
2241
+ target_version = GIT_REPO_VERSION_READ;
2242
+
2243
+ strbuf_release(&config);
2244
+ clear_repository_format(&repo_fmt);
2245
+ }
2246
+
2247
+ strbuf_addf(&repo_version, "%d", target_version);
2248
+ git_config_set("core.repositoryformatversion", repo_version.buf);
2249
+
2250
+ strbuf_release(&repo_version);
2251
}
2252
2253
static int is_reinit(void)
@@ -2333,7 +2347,7 @@ static int create_default_files(const char *template_path,
2347
adjust_shared_perm(repo_get_git_dir(the_repository));
2348
}
2349
2336
- initialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, 0);
2350
+ initialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, reinit);
2351
2352
/* Check filemode trustability */
2353
path = git_path_buf(&buf, "config");
t/t5504-fetch-receive-strict.sh
+3
-3
@@ -171,7 +171,7 @@ test_expect_success 'fsck with invalid or bogus skipList input' '
171
test_must_fail git -c fsck.skipList=does-not-exist -c fsck.missingEmail=ignore fsck 2>err &&
172
test_grep "could not open.*: does-not-exist" err &&
173
test_must_fail git -c fsck.skipList=.git/config -c fsck.missingEmail=ignore fsck 2>err &&
174
- test_grep "invalid object name: \[core\]" err
174
+ test_grep "invalid object name: " err
175
'
176
177
test_expect_success 'fsck with other accepted skipList input (comments & empty lines)' '
@@ -234,7 +234,7 @@ test_expect_success 'push with receive.fsck.skipList' '
234
test_grep "could not open.*: does-not-exist" err &&
235
git --git-dir=dst/.git config receive.fsck.skipList config &&
236
test_must_fail git push --porcelain dst bogus 2>err &&
237
- test_grep "invalid object name: \[core\]" err &&
237
+ test_grep "invalid object name: " err &&
238
239
git --git-dir=dst/.git config receive.fsck.skipList SKIP &&
240
git push --porcelain dst bogus
@@ -263,7 +263,7 @@ test_expect_success 'fetch with fetch.fsck.skipList' '
263
test_grep "could not open.*: does-not-exist" err &&
264
git --git-dir=dst/.git config fetch.fsck.skipList dst/.git/config &&
265
test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec 2>err &&
266
- test_grep "invalid object name: \[core\]" err &&
266
+ test_grep "invalid object name: " err &&
267
268
git --git-dir=dst/.git config fetch.fsck.skipList dst/.git/SKIP &&
269
git --git-dir=dst/.git fetch "file://$(pwd)" $refspec