diff options
author | Patrick Steinhardt <ps@pks.im> | 2020-04-02 13:26:13 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-02 13:26:13 +0200 |
commit | dfd7fcc41c588280f8fada2b86ecdb95bb1025a2 (patch) | |
tree | 067338d177e3cb2b79fbe69079b269baa623d9f5 | |
parent | e12991712920be44d0ff89431189f170f155f195 (diff) | |
parent | 06f0230073e0159933aa19d97fce0cbe3b9a3231 (diff) | |
download | libgit2-dfd7fcc41c588280f8fada2b86ecdb95bb1025a2.tar.gz |
Merge pull request #5388 from bk2204/repo-format-v1
Handle repository format v1
-rw-r--r-- | src/repository.c | 47 | ||||
-rw-r--r-- | tests/repo/open.c | 46 |
2 files changed, 84 insertions, 9 deletions
diff --git a/src/repository.c b/src/repository.c index fe0d696c6..da92b274c 100644 --- a/src/repository.c +++ b/src/repository.c @@ -62,7 +62,8 @@ static const struct { { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "worktrees", true } }; -static int check_repositoryformatversion(git_config *config); +static int check_repositoryformatversion(int *version, git_config *config); +static int check_extensions(git_config *config, int version); #define GIT_COMMONDIR_FILE "commondir" #define GIT_GITDIR_FILE "gitdir" @@ -72,6 +73,7 @@ static int check_repositoryformatversion(git_config *config); #define GIT_BRANCH_MASTER "master" #define GIT_REPO_VERSION 0 +#define GIT_REPO_MAX_VERSION 1 git_buf git_repository__reserved_names_win32[] = { { DOT_GIT, 0, CONST_STRLEN(DOT_GIT) }, @@ -813,6 +815,7 @@ int git_repository_open_ext( gitlink = GIT_BUF_INIT, commondir = GIT_BUF_INIT; git_repository *repo = NULL; git_config *config = NULL; + int version = 0; if (flags & GIT_REPOSITORY_OPEN_FROM_ENV) return _git_repository_open_ext_from_env(repo_ptr, start_path); @@ -854,7 +857,10 @@ int git_repository_open_ext( if (error < 0 && error != GIT_ENOTFOUND) goto cleanup; - if (config && (error = check_repositoryformatversion(config)) < 0) + if (config && (error = check_repositoryformatversion(&version, config)) < 0) + goto cleanup; + + if ((error = check_extensions(config, version) < 0)) goto cleanup; if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0) @@ -1350,11 +1356,11 @@ bool git_repository__reserved_names( } #endif -static int check_repositoryformatversion(git_config *config) +static int check_repositoryformatversion(int *version, git_config *config) { - int version, error; + int error; - error = git_config_get_int32(&version, config, "core.repositoryformatversion"); + error = git_config_get_int32(version, config, "core.repositoryformatversion"); /* git ignores this if the config variable isn't there */ if (error == GIT_ENOTFOUND) return 0; @@ -1362,16 +1368,35 @@ static int check_repositoryformatversion(git_config *config) if (error < 0) return -1; - if (GIT_REPO_VERSION < version) { + if (GIT_REPO_MAX_VERSION < *version) { git_error_set(GIT_ERROR_REPOSITORY, - "unsupported repository version %d. Only versions up to %d are supported.", - version, GIT_REPO_VERSION); + "unsupported repository version %d; only versions up to %d are supported", + *version, GIT_REPO_MAX_VERSION); return -1; } return 0; } +static int check_valid_extension(const git_config_entry *entry, void *payload) +{ + GIT_UNUSED(payload); + + if (!strcmp(entry->name, "extensions.noop")) + return 0; + + git_error_set(GIT_ERROR_REPOSITORY, "unsupported extension name %s", entry->name); + return -1; +} + +static int check_extensions(git_config *config, int version) +{ + if (version < 1) + return 0; + + return git_config_foreach_match(config, "^extensions\\.", check_valid_extension, NULL); +} + int git_repository_create_head(const char *git_dir, const char *ref_name) { git_buf ref_path = GIT_BUF_INIT; @@ -1583,11 +1608,15 @@ static int repo_init_config( git_config *config = NULL; bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0); bool is_reinit = ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0); + int version = 0; if ((error = repo_local_config(&config, &cfg_path, NULL, repo_dir)) < 0) goto cleanup; - if (is_reinit && (error = check_repositoryformatversion(config)) < 0) + if (is_reinit && (error = check_repositoryformatversion(&version, config)) < 0) + goto cleanup; + + if ((error = check_extensions(config, version) < 0)) goto cleanup; #define SET_REPO_CONFIG(TYPE, NAME, VAL) do { \ diff --git a/tests/repo/open.c b/tests/repo/open.c index 448ccdc87..0f4ecf5eb 100644 --- a/tests/repo/open.c +++ b/tests/repo/open.c @@ -35,7 +35,53 @@ void test_repo_open__format_version_1(void) git_config_free(config); git_repository_free(repo); + + git_repository_open(&repo, "empty_bare.git"); + cl_assert(git_repository_path(repo) != NULL); + cl_assert(git__suffixcmp(git_repository_path(repo), "/") == 0); + git_repository_free(repo); +} + +void test_repo_open__format_version_1_with_valid_extension(void) +{ + git_repository *repo; + git_config *config; + + repo = cl_git_sandbox_init("empty_bare.git"); + + cl_git_pass(git_repository_open(&repo, "empty_bare.git")); + cl_git_pass(git_repository_config(&config, repo)); + + cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 1)); + cl_git_pass(git_config_set_int32(config, "extensions.noop", 1)); + + git_config_free(config); + git_repository_free(repo); + + git_repository_open(&repo, "empty_bare.git"); + cl_assert(git_repository_path(repo) != NULL); + cl_assert(git__suffixcmp(git_repository_path(repo), "/") == 0); + git_repository_free(repo); +} + +void test_repo_open__format_version_1_with_invalid_extension(void) +{ + git_repository *repo; + git_config *config; + + repo = cl_git_sandbox_init("empty_bare.git"); + + cl_git_pass(git_repository_open(&repo, "empty_bare.git")); + cl_git_pass(git_repository_config(&config, repo)); + + cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 1)); + cl_git_pass(git_config_set_int32(config, "extensions.invalid", 1)); + + git_config_free(config); + git_repository_free(repo); + cl_git_fail(git_repository_open(&repo, "empty_bare.git")); + git_repository_free(repo); } void test_repo_open__standard_empty_repo_through_gitdir(void) |