Skip to content

Commit dfd7fcc

Browse files
authored
Merge pull request libgit2#5388 from bk2204/repo-format-v1
Handle repository format v1
2 parents e129917 + 06f0230 commit dfd7fcc

File tree

2 files changed

+84
-9
lines changed

2 files changed

+84
-9
lines changed

src/repository.c

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ static const struct {
6262
{ GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "worktrees", true }
6363
};
6464

65-
static int check_repositoryformatversion(git_config *config);
65+
static int check_repositoryformatversion(int *version, git_config *config);
66+
static int check_extensions(git_config *config, int version);
6667

6768
#define GIT_COMMONDIR_FILE "commondir"
6869
#define GIT_GITDIR_FILE "gitdir"
@@ -72,6 +73,7 @@ static int check_repositoryformatversion(git_config *config);
7273
#define GIT_BRANCH_MASTER "master"
7374

7475
#define GIT_REPO_VERSION 0
76+
#define GIT_REPO_MAX_VERSION 1
7577

7678
git_buf git_repository__reserved_names_win32[] = {
7779
{ DOT_GIT, 0, CONST_STRLEN(DOT_GIT) },
@@ -813,6 +815,7 @@ int git_repository_open_ext(
813815
gitlink = GIT_BUF_INIT, commondir = GIT_BUF_INIT;
814816
git_repository *repo = NULL;
815817
git_config *config = NULL;
818+
int version = 0;
816819

817820
if (flags & GIT_REPOSITORY_OPEN_FROM_ENV)
818821
return _git_repository_open_ext_from_env(repo_ptr, start_path);
@@ -854,7 +857,10 @@ int git_repository_open_ext(
854857
if (error < 0 && error != GIT_ENOTFOUND)
855858
goto cleanup;
856859

857-
if (config && (error = check_repositoryformatversion(config)) < 0)
860+
if (config && (error = check_repositoryformatversion(&version, config)) < 0)
861+
goto cleanup;
862+
863+
if ((error = check_extensions(config, version) < 0))
858864
goto cleanup;
859865

860866
if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0)
@@ -1350,28 +1356,47 @@ bool git_repository__reserved_names(
13501356
}
13511357
#endif
13521358

1353-
static int check_repositoryformatversion(git_config *config)
1359+
static int check_repositoryformatversion(int *version, git_config *config)
13541360
{
1355-
int version, error;
1361+
int error;
13561362

1357-
error = git_config_get_int32(&version, config, "core.repositoryformatversion");
1363+
error = git_config_get_int32(version, config, "core.repositoryformatversion");
13581364
/* git ignores this if the config variable isn't there */
13591365
if (error == GIT_ENOTFOUND)
13601366
return 0;
13611367

13621368
if (error < 0)
13631369
return -1;
13641370

1365-
if (GIT_REPO_VERSION < version) {
1371+
if (GIT_REPO_MAX_VERSION < *version) {
13661372
git_error_set(GIT_ERROR_REPOSITORY,
1367-
"unsupported repository version %d. Only versions up to %d are supported.",
1368-
version, GIT_REPO_VERSION);
1373+
"unsupported repository version %d; only versions up to %d are supported",
1374+
*version, GIT_REPO_MAX_VERSION);
13691375
return -1;
13701376
}
13711377

13721378
return 0;
13731379
}
13741380

1381+
static int check_valid_extension(const git_config_entry *entry, void *payload)
1382+
{
1383+
GIT_UNUSED(payload);
1384+
1385+
if (!strcmp(entry->name, "extensions.noop"))
1386+
return 0;
1387+
1388+
git_error_set(GIT_ERROR_REPOSITORY, "unsupported extension name %s", entry->name);
1389+
return -1;
1390+
}
1391+
1392+
static int check_extensions(git_config *config, int version)
1393+
{
1394+
if (version < 1)
1395+
return 0;
1396+
1397+
return git_config_foreach_match(config, "^extensions\\.", check_valid_extension, NULL);
1398+
}
1399+
13751400
int git_repository_create_head(const char *git_dir, const char *ref_name)
13761401
{
13771402
git_buf ref_path = GIT_BUF_INIT;
@@ -1583,11 +1608,15 @@ static int repo_init_config(
15831608
git_config *config = NULL;
15841609
bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0);
15851610
bool is_reinit = ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0);
1611+
int version = 0;
15861612

15871613
if ((error = repo_local_config(&config, &cfg_path, NULL, repo_dir)) < 0)
15881614
goto cleanup;
15891615

1590-
if (is_reinit && (error = check_repositoryformatversion(config)) < 0)
1616+
if (is_reinit && (error = check_repositoryformatversion(&version, config)) < 0)
1617+
goto cleanup;
1618+
1619+
if ((error = check_extensions(config, version) < 0))
15911620
goto cleanup;
15921621

15931622
#define SET_REPO_CONFIG(TYPE, NAME, VAL) do { \

tests/repo/open.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,53 @@ void test_repo_open__format_version_1(void)
3535

3636
git_config_free(config);
3737
git_repository_free(repo);
38+
39+
git_repository_open(&repo, "empty_bare.git");
40+
cl_assert(git_repository_path(repo) != NULL);
41+
cl_assert(git__suffixcmp(git_repository_path(repo), "/") == 0);
42+
git_repository_free(repo);
43+
}
44+
45+
void test_repo_open__format_version_1_with_valid_extension(void)
46+
{
47+
git_repository *repo;
48+
git_config *config;
49+
50+
repo = cl_git_sandbox_init("empty_bare.git");
51+
52+
cl_git_pass(git_repository_open(&repo, "empty_bare.git"));
53+
cl_git_pass(git_repository_config(&config, repo));
54+
55+
cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 1));
56+
cl_git_pass(git_config_set_int32(config, "extensions.noop", 1));
57+
58+
git_config_free(config);
59+
git_repository_free(repo);
60+
61+
git_repository_open(&repo, "empty_bare.git");
62+
cl_assert(git_repository_path(repo) != NULL);
63+
cl_assert(git__suffixcmp(git_repository_path(repo), "/") == 0);
64+
git_repository_free(repo);
65+
}
66+
67+
void test_repo_open__format_version_1_with_invalid_extension(void)
68+
{
69+
git_repository *repo;
70+
git_config *config;
71+
72+
repo = cl_git_sandbox_init("empty_bare.git");
73+
74+
cl_git_pass(git_repository_open(&repo, "empty_bare.git"));
75+
cl_git_pass(git_repository_config(&config, repo));
76+
77+
cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 1));
78+
cl_git_pass(git_config_set_int32(config, "extensions.invalid", 1));
79+
80+
git_config_free(config);
81+
git_repository_free(repo);
82+
3883
cl_git_fail(git_repository_open(&repo, "empty_bare.git"));
84+
git_repository_free(repo);
3985
}
4086

4187
void test_repo_open__standard_empty_repo_through_gitdir(void)

0 commit comments

Comments
 (0)