Skip to content

Commit c28a2d0

Browse files
committed
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
2 parents 3161cc6 + ec91ffc commit c28a2d0

File tree

3 files changed

+85
-16
lines changed

3 files changed

+85
-16
lines changed

cache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,7 @@ struct repository_format {
10441044
int hash_algo;
10451045
char *work_tree;
10461046
struct string_list unknown_extensions;
1047+
struct string_list v1_only_extensions;
10471048
};
10481049

10491050
/*
@@ -1057,6 +1058,7 @@ struct repository_format {
10571058
.is_bare = -1, \
10581059
.hash_algo = GIT_HASH_SHA1, \
10591060
.unknown_extensions = STRING_LIST_INIT_DUP, \
1061+
.v1_only_extensions = STRING_LIST_INIT_DUP, \
10601062
}
10611063

10621064
/*

setup.c

Lines changed: 80 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,54 @@ static int read_worktree_config(const char *var, const char *value, void *vdata)
447447
return 0;
448448
}
449449

450+
enum extension_result {
451+
EXTENSION_ERROR = -1, /* compatible with error(), etc */
452+
EXTENSION_UNKNOWN = 0,
453+
EXTENSION_OK = 1
454+
};
455+
456+
/*
457+
* Do not add new extensions to this function. It handles extensions which are
458+
* respected even in v0-format repositories for historical compatibility.
459+
*/
460+
static enum extension_result handle_extension_v0(const char *var,
461+
const char *value,
462+
const char *ext,
463+
struct repository_format *data)
464+
{
465+
if (!strcmp(ext, "noop")) {
466+
return EXTENSION_OK;
467+
} else if (!strcmp(ext, "preciousobjects")) {
468+
data->precious_objects = git_config_bool(var, value);
469+
return EXTENSION_OK;
470+
} else if (!strcmp(ext, "partialclone")) {
471+
if (!value)
472+
return config_error_nonbool(var);
473+
data->partial_clone = xstrdup(value);
474+
return EXTENSION_OK;
475+
} else if (!strcmp(ext, "worktreeconfig")) {
476+
data->worktree_config = git_config_bool(var, value);
477+
return EXTENSION_OK;
478+
}
479+
480+
return EXTENSION_UNKNOWN;
481+
}
482+
483+
/*
484+
* Record any new extensions in this function.
485+
*/
486+
static enum extension_result handle_extension(const char *var,
487+
const char *value,
488+
const char *ext,
489+
struct repository_format *data)
490+
{
491+
if (!strcmp(ext, "noop-v1")) {
492+
return EXTENSION_OK;
493+
}
494+
495+
return EXTENSION_UNKNOWN;
496+
}
497+
450498
static int check_repo_format(const char *var, const char *value, void *vdata)
451499
{
452500
struct repository_format *data = vdata;
@@ -455,23 +503,25 @@ static int check_repo_format(const char *var, const char *value, void *vdata)
455503
if (strcmp(var, "core.repositoryformatversion") == 0)
456504
data->version = git_config_int(var, value);
457505
else if (skip_prefix(var, "extensions.", &ext)) {
458-
/*
459-
* record any known extensions here; otherwise,
460-
* we fall through to recording it as unknown, and
461-
* check_repository_format will complain
462-
*/
463-
if (!strcmp(ext, "noop"))
464-
;
465-
else if (!strcmp(ext, "preciousobjects"))
466-
data->precious_objects = git_config_bool(var, value);
467-
else if (!strcmp(ext, "partialclone")) {
468-
if (!value)
469-
return config_error_nonbool(var);
470-
data->partial_clone = xstrdup(value);
471-
} else if (!strcmp(ext, "worktreeconfig"))
472-
data->worktree_config = git_config_bool(var, value);
473-
else
506+
switch (handle_extension_v0(var, value, ext, data)) {
507+
case EXTENSION_ERROR:
508+
return -1;
509+
case EXTENSION_OK:
510+
return 0;
511+
case EXTENSION_UNKNOWN:
512+
break;
513+
}
514+
515+
switch (handle_extension(var, value, ext, data)) {
516+
case EXTENSION_ERROR:
517+
return -1;
518+
case EXTENSION_OK:
519+
string_list_append(&data->v1_only_extensions, ext);
520+
return 0;
521+
case EXTENSION_UNKNOWN:
474522
string_list_append(&data->unknown_extensions, ext);
523+
return 0;
524+
}
475525
}
476526

477527
return read_worktree_config(var, value, vdata);
@@ -510,6 +560,7 @@ static int check_repository_format_gently(const char *gitdir, struct repository_
510560
set_repository_format_partial_clone(candidate->partial_clone);
511561
repository_format_worktree_config = candidate->worktree_config;
512562
string_list_clear(&candidate->unknown_extensions, 0);
563+
string_list_clear(&candidate->v1_only_extensions, 0);
513564

514565
if (repository_format_worktree_config) {
515566
/*
@@ -588,6 +639,7 @@ int read_repository_format(struct repository_format *format, const char *path)
588639
void clear_repository_format(struct repository_format *format)
589640
{
590641
string_list_clear(&format->unknown_extensions, 0);
642+
string_list_clear(&format->v1_only_extensions, 0);
591643
free(format->work_tree);
592644
free(format->partial_clone);
593645
init_repository_format(format);
@@ -613,6 +665,18 @@ int verify_repository_format(const struct repository_format *format,
613665
return -1;
614666
}
615667

668+
if (format->version == 0 && format->v1_only_extensions.nr) {
669+
int i;
670+
671+
strbuf_addstr(err,
672+
_("repo version is 0, but v1-only extensions found:"));
673+
674+
for (i = 0; i < format->v1_only_extensions.nr; i++)
675+
strbuf_addf(err, "\n\t%s",
676+
format->v1_only_extensions.items[i].string);
677+
return -1;
678+
}
679+
616680
return 0;
617681
}
618682

t/t1302-repo-version.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ allow 1
8787
allow 1 noop
8888
abort 1 no-such-extension
8989
allow 0 no-such-extension
90+
allow 0 noop
91+
abort 0 noop-v1
92+
allow 1 noop-v1
9093
EOF
9194

9295
test_expect_success 'precious-objects allowed' '

0 commit comments

Comments
 (0)