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;
|
int hash_algo;
|
||||||
char *work_tree;
|
char *work_tree;
|
||||||
struct string_list unknown_extensions;
|
struct string_list unknown_extensions;
|
||||||
|
struct string_list v1_only_extensions;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1057,6 +1058,7 @@ struct repository_format {
|
|||||||
.is_bare = -1, \
|
.is_bare = -1, \
|
||||||
.hash_algo = GIT_HASH_SHA1, \
|
.hash_algo = GIT_HASH_SHA1, \
|
||||||
.unknown_extensions = STRING_LIST_INIT_DUP, \
|
.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;
|
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)
|
static int check_repo_format(const char *var, const char *value, void *vdata)
|
||||||
{
|
{
|
||||||
struct repository_format *data = 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)
|
if (strcmp(var, "core.repositoryformatversion") == 0)
|
||||||
data->version = git_config_int(var, value);
|
data->version = git_config_int(var, value);
|
||||||
else if (skip_prefix(var, "extensions.", &ext)) {
|
else if (skip_prefix(var, "extensions.", &ext)) {
|
||||||
/*
|
switch (handle_extension_v0(var, value, ext, data)) {
|
||||||
* record any known extensions here; otherwise,
|
case EXTENSION_ERROR:
|
||||||
* we fall through to recording it as unknown, and
|
return -1;
|
||||||
* check_repository_format will complain
|
case EXTENSION_OK:
|
||||||
*/
|
return 0;
|
||||||
if (!strcmp(ext, "noop"))
|
case EXTENSION_UNKNOWN:
|
||||||
;
|
break;
|
||||||
else if (!strcmp(ext, "preciousobjects"))
|
}
|
||||||
data->precious_objects = git_config_bool(var, value);
|
|
||||||
else if (!strcmp(ext, "partialclone")) {
|
switch (handle_extension(var, value, ext, data)) {
|
||||||
if (!value)
|
case EXTENSION_ERROR:
|
||||||
return config_error_nonbool(var);
|
return -1;
|
||||||
data->partial_clone = xstrdup(value);
|
case EXTENSION_OK:
|
||||||
} else if (!strcmp(ext, "worktreeconfig"))
|
string_list_append(&data->v1_only_extensions, ext);
|
||||||
data->worktree_config = git_config_bool(var, value);
|
return 0;
|
||||||
else
|
case EXTENSION_UNKNOWN:
|
||||||
string_list_append(&data->unknown_extensions, ext);
|
string_list_append(&data->unknown_extensions, ext);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return read_worktree_config(var, value, vdata);
|
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);
|
set_repository_format_partial_clone(candidate->partial_clone);
|
||||||
repository_format_worktree_config = candidate->worktree_config;
|
repository_format_worktree_config = candidate->worktree_config;
|
||||||
string_list_clear(&candidate->unknown_extensions, 0);
|
string_list_clear(&candidate->unknown_extensions, 0);
|
||||||
|
string_list_clear(&candidate->v1_only_extensions, 0);
|
||||||
|
|
||||||
if (repository_format_worktree_config) {
|
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)
|
void clear_repository_format(struct repository_format *format)
|
||||||
{
|
{
|
||||||
string_list_clear(&format->unknown_extensions, 0);
|
string_list_clear(&format->unknown_extensions, 0);
|
||||||
|
string_list_clear(&format->v1_only_extensions, 0);
|
||||||
free(format->work_tree);
|
free(format->work_tree);
|
||||||
free(format->partial_clone);
|
free(format->partial_clone);
|
||||||
init_repository_format(format);
|
init_repository_format(format);
|
||||||
@ -613,6 +665,18 @@ int verify_repository_format(const struct repository_format *format,
|
|||||||
return -1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +87,9 @@ allow 1
|
|||||||
allow 1 noop
|
allow 1 noop
|
||||||
abort 1 no-such-extension
|
abort 1 no-such-extension
|
||||||
allow 0 no-such-extension
|
allow 0 no-such-extension
|
||||||
|
allow 0 noop
|
||||||
|
abort 0 noop-v1
|
||||||
|
allow 1 noop-v1
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
test_expect_success 'precious-objects allowed' '
|
test_expect_success 'precious-objects allowed' '
|
||||||
|
Loading…
Reference in New Issue
Block a user