repository: add a helper function to perform repository format upgrade
In version 1 of repository format, "extensions" gained special meaning and it is safer to avoid upgrading when there are pre-existing extensions. Make list-objects-filter to use the helper function instead of setting repository version directly as a prerequisite of exposing the upgrade capability. Signed-off-by: Xin Li <delphij@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Xin Li committed
Jun 5, 2020 at 02:10 UTC
16af5f1abb2b3291f96a248698449c48c6a0ec36
4 files changed
+38
-1
cache.h
+1
@@ -1042,6 +1042,7 @@ struct repository_format {
1042
int worktree_config;
1043
int is_bare;
1044
int hash_algo;
1045
+ int has_extensions;
1046
char *work_tree;
1047
struct string_list unknown_extensions;
1048
};
list-objects-filter-options.c
+2
-1
@@ -326,7 +326,8 @@ void partial_clone_register(
326
327
/* Check if it is already registered */
328
if (!promisor_remote_find(remote)) {
329
- git_config_set("core.repositoryformatversion", "1");
329
+ if (upgrade_repository_format(1) < 0)
330
+ die(_("unable to upgrade repository format to support partial clone"));
331
332
/* Add promisor config for the remote */
333
cfg_name = xstrfmt("remote.%s.promisor", remote);
repository.h
+6
@@ -196,4 +196,10 @@ void repo_update_index_if_able(struct repository *, struct lock_file *);
196
197
void prepare_repo_settings(struct repository *r);
198
199
+/*
200
+ * Return 1 if upgrade repository format to target_version succeeded,
201
+ * 0 if no upgrade is necessary, and -1 when upgrade is not possible.
202
+ */
203
+int upgrade_repository_format(int target_version);
204
+
205
#endif /* REPOSITORY_H */
setup.c
+29
@@ -455,6 +455,7 @@ static int check_repo_format(const char *var, const char *value, void *vdata)
455
if (strcmp(var, "core.repositoryformatversion") == 0)
456
data->version = git_config_int(var, value);
457
else if (skip_prefix(var, "extensions.", &ext)) {
458
+ data->has_extensions = 1;
459
/*
460
* record any known extensions here; otherwise,
461
* we fall through to recording it as unknown, and
@@ -538,6 +539,34 @@ static int check_repository_format_gently(const char *gitdir, struct repository_
539
return 0;
540
}
541
542
+int upgrade_repository_format(int target_version)
543
+{
544
+ struct strbuf sb = STRBUF_INIT;
545
+ struct strbuf err = STRBUF_INIT;
546
+ struct strbuf repo_version = STRBUF_INIT;
547
+ struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
548
+
549
+ strbuf_git_common_path(&sb, the_repository, "config");
550
+ read_repository_format(&repo_fmt, sb.buf);
551
+ strbuf_release(&sb);
552
+
553
+ if (repo_fmt.version >= target_version)
554
+ return 0;
555
+
556
+ if (verify_repository_format(&repo_fmt, &err) < 0 ||
557
+ (!repo_fmt.version && repo_fmt.has_extensions)) {
558
+ warning("unable to upgrade repository format from %d to %d: %s",
559
+ repo_fmt.version, target_version, err.buf);
560
+ strbuf_release(&err);
561
+ return -1;
562
+ }
563
+
564
+ strbuf_addf(&repo_version, "%d", target_version);
565
+ git_config_set("core.repositoryformatversion", repo_version.buf);
566
+ strbuf_release(&repo_version);
567
+ return 1;
568
+}
569
+
570
static void init_repository_format(struct repository_format *format)
571
{
572
const struct repository_format fresh = REPOSITORY_FORMAT_INIT;