Merge branch 'jk/reject-newer-extensions-in-v0' into master
With the base fix to 2.27 regresion, any new extensions in a v0 repository would still be silently honored, which is not quite right. Instead, complain and die loudly. * jk/reject-newer-extensions-in-v0: verify_repository_format(): complain about new extensions in v0 repo
This commit is contained in:
commit
c28a2d0c12
2
cache.h
2
cache.h
@ -1044,6 +1044,7 @@ struct repository_format {
|
||||
int hash_algo;
|
||||
char *work_tree;
|
||||
struct string_list unknown_extensions;
|
||||
struct string_list v1_only_extensions;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1057,6 +1058,7 @@ struct repository_format {
|
||||
.is_bare = -1, \
|
||||
.hash_algo = GIT_HASH_SHA1, \
|
||||
.unknown_extensions = STRING_LIST_INIT_DUP, \
|
||||
.v1_only_extensions = STRING_LIST_INIT_DUP, \
|
||||
}
|
||||
|
||||
/*
|
||||
|
96
setup.c
96
setup.c
@ -447,6 +447,54 @@ static int read_worktree_config(const char *var, const char *value, void *vdata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum extension_result {
|
||||
EXTENSION_ERROR = -1, /* compatible with error(), etc */
|
||||
EXTENSION_UNKNOWN = 0,
|
||||
EXTENSION_OK = 1
|
||||
};
|
||||
|
||||
/*
|
||||
* Do not add new extensions to this function. It handles extensions which are
|
||||
* respected even in v0-format repositories for historical compatibility.
|
||||
*/
|
||||
static enum extension_result handle_extension_v0(const char *var,
|
||||
const char *value,
|
||||
const char *ext,
|
||||
struct repository_format *data)
|
||||
{
|
||||
if (!strcmp(ext, "noop")) {
|
||||
return EXTENSION_OK;
|
||||
} else if (!strcmp(ext, "preciousobjects")) {
|
||||
data->precious_objects = git_config_bool(var, value);
|
||||
return EXTENSION_OK;
|
||||
} else if (!strcmp(ext, "partialclone")) {
|
||||
if (!value)
|
||||
return config_error_nonbool(var);
|
||||
data->partial_clone = xstrdup(value);
|
||||
return EXTENSION_OK;
|
||||
} else if (!strcmp(ext, "worktreeconfig")) {
|
||||
data->worktree_config = git_config_bool(var, value);
|
||||
return EXTENSION_OK;
|
||||
}
|
||||
|
||||
return EXTENSION_UNKNOWN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Record any new extensions in this function.
|
||||
*/
|
||||
static enum extension_result handle_extension(const char *var,
|
||||
const char *value,
|
||||
const char *ext,
|
||||
struct repository_format *data)
|
||||
{
|
||||
if (!strcmp(ext, "noop-v1")) {
|
||||
return EXTENSION_OK;
|
||||
}
|
||||
|
||||
return EXTENSION_UNKNOWN;
|
||||
}
|
||||
|
||||
static int check_repo_format(const char *var, const char *value, void *vdata)
|
||||
{
|
||||
struct repository_format *data = vdata;
|
||||
@ -455,23 +503,25 @@ static int check_repo_format(const char *var, const char *value, void *vdata)
|
||||
if (strcmp(var, "core.repositoryformatversion") == 0)
|
||||
data->version = git_config_int(var, value);
|
||||
else if (skip_prefix(var, "extensions.", &ext)) {
|
||||
/*
|
||||
* record any known extensions here; otherwise,
|
||||
* we fall through to recording it as unknown, and
|
||||
* check_repository_format will complain
|
||||
*/
|
||||
if (!strcmp(ext, "noop"))
|
||||
;
|
||||
else if (!strcmp(ext, "preciousobjects"))
|
||||
data->precious_objects = git_config_bool(var, value);
|
||||
else if (!strcmp(ext, "partialclone")) {
|
||||
if (!value)
|
||||
return config_error_nonbool(var);
|
||||
data->partial_clone = xstrdup(value);
|
||||
} else if (!strcmp(ext, "worktreeconfig"))
|
||||
data->worktree_config = git_config_bool(var, value);
|
||||
else
|
||||
switch (handle_extension_v0(var, value, ext, data)) {
|
||||
case EXTENSION_ERROR:
|
||||
return -1;
|
||||
case EXTENSION_OK:
|
||||
return 0;
|
||||
case EXTENSION_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (handle_extension(var, value, ext, data)) {
|
||||
case EXTENSION_ERROR:
|
||||
return -1;
|
||||
case EXTENSION_OK:
|
||||
string_list_append(&data->v1_only_extensions, ext);
|
||||
return 0;
|
||||
case EXTENSION_UNKNOWN:
|
||||
string_list_append(&data->unknown_extensions, ext);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return read_worktree_config(var, value, vdata);
|
||||
@ -510,6 +560,7 @@ static int check_repository_format_gently(const char *gitdir, struct repository_
|
||||
set_repository_format_partial_clone(candidate->partial_clone);
|
||||
repository_format_worktree_config = candidate->worktree_config;
|
||||
string_list_clear(&candidate->unknown_extensions, 0);
|
||||
string_list_clear(&candidate->v1_only_extensions, 0);
|
||||
|
||||
if (repository_format_worktree_config) {
|
||||
/*
|
||||
@ -588,6 +639,7 @@ int read_repository_format(struct repository_format *format, const char *path)
|
||||
void clear_repository_format(struct repository_format *format)
|
||||
{
|
||||
string_list_clear(&format->unknown_extensions, 0);
|
||||
string_list_clear(&format->v1_only_extensions, 0);
|
||||
free(format->work_tree);
|
||||
free(format->partial_clone);
|
||||
init_repository_format(format);
|
||||
@ -613,6 +665,18 @@ int verify_repository_format(const struct repository_format *format,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (format->version == 0 && format->v1_only_extensions.nr) {
|
||||
int i;
|
||||
|
||||
strbuf_addstr(err,
|
||||
_("repo version is 0, but v1-only extensions found:"));
|
||||
|
||||
for (i = 0; i < format->v1_only_extensions.nr; i++)
|
||||
strbuf_addf(err, "\n\t%s",
|
||||
format->v1_only_extensions.items[i].string);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -87,6 +87,9 @@ allow 1
|
||||
allow 1 noop
|
||||
abort 1 no-such-extension
|
||||
allow 0 no-such-extension
|
||||
allow 0 noop
|
||||
abort 0 noop-v1
|
||||
allow 1 noop-v1
|
||||
EOF
|
||||
|
||||
test_expect_success 'precious-objects allowed' '
|
||||
|
Loading…
Reference in New Issue
Block a user