]> git.ipfire.org Git - thirdparty/git.git/commitdiff
repository: add a helper function to perform repository format upgrade
authorXin Li <delphij@google.com>
Fri, 5 Jun 2020 09:10:01 +0000 (02:10 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 5 Jun 2020 17:13:30 +0000 (10:13 -0700)
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>
cache.h
list-objects-filter-options.c
repository.h
setup.c

diff --git a/cache.h b/cache.h
index 0f0485ecfe2cd9a2270cffcec3552e901658539a..e5885cc9ead57a4eba10ad5263f58b94439feb85 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -1042,6 +1042,7 @@ struct repository_format {
        int worktree_config;
        int is_bare;
        int hash_algo;
+       int has_extensions;
        char *work_tree;
        struct string_list unknown_extensions;
 };
index 256bcfbdfe666db068599baeb8aae4c09a3ac8fb..3553ad7b0a759e13258a267960caf2ee15b6f019 100644 (file)
@@ -326,7 +326,8 @@ void partial_clone_register(
 
        /* Check if it is already registered */
        if (!promisor_remote_find(remote)) {
-               git_config_set("core.repositoryformatversion", "1");
+               if (upgrade_repository_format(1) < 0)
+                       die(_("unable to upgrade repository format to support partial clone"));
 
                /* Add promisor config for the remote */
                cfg_name = xstrfmt("remote.%s.promisor", remote);
index 6534fbb7b31301aa514c6cfad4f55b03289228b5..3c1f7d54bd37a55f6cd1b1ac1f936dc0c17b3dab 100644 (file)
@@ -196,4 +196,10 @@ void repo_update_index_if_able(struct repository *, struct lock_file *);
 
 void prepare_repo_settings(struct repository *r);
 
+/*
+ * Return 1 if upgrade repository format to target_version succeeded,
+ * 0 if no upgrade is necessary, and -1 when upgrade is not possible.
+ */
+int upgrade_repository_format(int target_version);
+
 #endif /* REPOSITORY_H */
diff --git a/setup.c b/setup.c
index 65fe5ecefbe196eba04070978bc668b9af17257d..597b41b822cf8a371681d1778de2451cb1bc243b 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -455,6 +455,7 @@ 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)) {
+               data->has_extensions = 1;
                /*
                 * record any known extensions here; otherwise,
                 * we fall through to recording it as unknown, and
@@ -538,6 +539,34 @@ static int check_repository_format_gently(const char *gitdir, struct repository_
        return 0;
 }
 
+int upgrade_repository_format(int target_version)
+{
+       struct strbuf sb = STRBUF_INIT;
+       struct strbuf err = STRBUF_INIT;
+       struct strbuf repo_version = STRBUF_INIT;
+       struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
+
+       strbuf_git_common_path(&sb, the_repository, "config");
+       read_repository_format(&repo_fmt, sb.buf);
+       strbuf_release(&sb);
+
+       if (repo_fmt.version >= target_version)
+               return 0;
+
+       if (verify_repository_format(&repo_fmt, &err) < 0 ||
+           (!repo_fmt.version && repo_fmt.has_extensions)) {
+               warning("unable to upgrade repository format from %d to %d: %s",
+                       repo_fmt.version, target_version, err.buf);
+               strbuf_release(&err);
+               return -1;
+       }
+
+       strbuf_addf(&repo_version, "%d", target_version);
+       git_config_set("core.repositoryformatversion", repo_version.buf);
+       strbuf_release(&repo_version);
+       return 1;
+}
+
 static void init_repository_format(struct repository_format *format)
 {
        const struct repository_format fresh = REPOSITORY_FORMAT_INIT;