Skip to content

Commit

Permalink
Merge branch 'jk/reject-newer-extensions-in-v0' into master
Browse files Browse the repository at this point in the history
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
  • Loading branch information
gitster committed Jul 30, 2020
2 parents 3161cc6 + ec91ffc commit c28a2d0
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 16 deletions.
2 changes: 2 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,7 @@ struct repository_format {
int hash_algo;
char *work_tree;
struct string_list unknown_extensions;
struct string_list v1_only_extensions;
};

/*
Expand All @@ -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, \
}

/*
Expand Down
96 changes: 80 additions & 16 deletions setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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) {
/*
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down
3 changes: 3 additions & 0 deletions t/t1302-repo-version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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' '
Expand Down

0 comments on commit c28a2d0

Please sign in to comment.