]> git.ipfire.org Git - thirdparty/git.git/blobdiff - setup.c
remote-mediawiki tests: use a more idiomatic dispatch table
[thirdparty/git.git] / setup.c
diff --git a/setup.c b/setup.c
index 3a81307602e2b029115f0c6db2c985508e590bd1..c04cd25a30dfe0e97d93087c0e7f29910d1b46a5 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -447,6 +447,63 @@ 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;
+       } else if (!strcmp(ext, "objectformat")) {
+               int format;
+
+               if (!value)
+                       return config_error_nonbool(var);
+               format = hash_algo_by_name(value);
+               if (format == GIT_HASH_UNKNOWN)
+                       return error("invalid value for 'extensions.objectformat'");
+               data->hash_algo = format;
+               return EXTENSION_OK;
+       }
+       return EXTENSION_UNKNOWN;
+}
+
 static int check_repo_format(const char *var, const char *value, void *vdata)
 {
        struct repository_format *data = vdata;
@@ -455,23 +512,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);
@@ -510,6 +569,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) {
                /*
@@ -588,6 +648,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);
@@ -613,6 +674,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;
 }