diff options
| author | brian m. carlson <sandals@crustytoothpaste.net> | 2020-02-07 00:33:52 +0000 |
|---|---|---|
| committer | brian m. carlson <sandals@crustytoothpaste.net> | 2020-02-11 00:41:31 +0000 |
| commit | 06f0230073e0159933aa19d97fce0cbe3b9a3231 (patch) | |
| tree | 9977ad86fa05688aec4de9f6de675a0494352f1c /src | |
| parent | ee3307a183e39d602b25fa94831c6fc09e7c1b61 (diff) | |
| download | libgit2-06f0230073e0159933aa19d97fce0cbe3b9a3231.tar.gz | |
repository: handle format v1
Git has supported repository format version 1 for some time. This
format is just like version 0, but it supports extensions.
Implementations must reject extensions that they don't support.
Add support for this format version and reject any extensions but
extensions.noop, which is the only extension we currently support.
While we're at it, also clean up an error message.
Diffstat (limited to 'src')
| -rw-r--r-- | src/repository.c | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/src/repository.c b/src/repository.c index 2469e13e6..721ce5e90 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) }, @@ -804,6 +806,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); @@ -845,7 +848,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) @@ -1341,11 +1347,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; @@ -1353,16 +1359,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; @@ -1574,11 +1599,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 { \ |
