Merge pull request #5388 from bk2204/repo-format-v1 Handle repository format v1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
diff --git a/src/repository.c b/src/repository.c
index fe0d696..da92b27 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 448ccdc..0f4ecf5 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)