aboutsummaryrefslogtreecommitdiff
path: root/setup.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2026-03-04 10:52:58 -0800
committerJunio C Hamano <gitster@pobox.com>2026-03-04 10:52:59 -0800
commit1d0a2acb78f157d39937a088548e561b27722e8d (patch)
tree4251f1f0f2a4ce4a6ee6f71e75d17d0bdbe4f948 /setup.c
parent50d063e335afd5828fbb9de2f2b2fb44fd884d2b (diff)
parent53592d68e86814fcc4a8df6cc38340597e56fe5a (diff)
downloadgit-1d0a2acb78f157d39937a088548e561b27722e8d.tar.xz
Merge branch 'kn/ref-location'
Allow the directory in which reference backends store their data to be specified. * kn/ref-location: refs: add GIT_REFERENCE_BACKEND to specify reference backend refs: allow reference location in refstorage config refs: receive and use the reference storage payload refs: move out stub modification to generic layer refs: extract out `refs_create_refdir_stubs()` setup: don't modify repo in `create_reference_database()`
Diffstat (limited to 'setup.c')
-rw-r--r--setup.c96
1 files changed, 84 insertions, 12 deletions
diff --git a/setup.c b/setup.c
index c8336eb20e..393b970ae4 100644
--- a/setup.c
+++ b/setup.c
@@ -631,6 +631,21 @@ static enum extension_result handle_extension_v0(const char *var,
return EXTENSION_UNKNOWN;
}
+static void parse_reference_uri(const char *value, char **format,
+ char **payload)
+{
+ const char *schema_end;
+
+ schema_end = strstr(value, "://");
+ if (!schema_end) {
+ *format = xstrdup(value);
+ *payload = NULL;
+ } else {
+ *format = xstrndup(value, schema_end - value);
+ *payload = xstrdup_or_null(schema_end + 3);
+ }
+}
+
/*
* Record any new extensions in this function.
*/
@@ -673,10 +688,17 @@ static enum extension_result handle_extension(const char *var,
return EXTENSION_OK;
} else if (!strcmp(ext, "refstorage")) {
unsigned int format;
+ char *format_str;
if (!value)
return config_error_nonbool(var);
- format = ref_storage_format_by_name(value);
+
+ parse_reference_uri(value, &format_str,
+ &data->ref_storage_payload);
+
+ format = ref_storage_format_by_name(format_str);
+ free(format_str);
+
if (format == REF_STORAGE_FORMAT_UNKNOWN)
return error(_("invalid value for '%s': '%s'"),
"extensions.refstorage", value);
@@ -852,6 +874,7 @@ void clear_repository_format(struct repository_format *format)
string_list_clear(&format->v1_only_extensions, 0);
free(format->work_tree);
free(format->partial_clone);
+ free(format->ref_storage_payload);
init_repository_format(format);
}
@@ -1817,6 +1840,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
static struct strbuf cwd = STRBUF_INIT;
struct strbuf dir = STRBUF_INIT, gitdir = STRBUF_INIT, report = STRBUF_INIT;
const char *prefix = NULL;
+ const char *ref_backend_uri;
struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
/*
@@ -1944,7 +1968,8 @@ const char *setup_git_directory_gently(int *nongit_ok)
repo_set_compat_hash_algo(the_repository,
repo_fmt.compat_hash_algo);
repo_set_ref_storage_format(the_repository,
- repo_fmt.ref_storage_format);
+ repo_fmt.ref_storage_format,
+ repo_fmt.ref_storage_payload);
the_repository->repository_format_worktree_config =
repo_fmt.worktree_config;
the_repository->repository_format_relative_worktrees =
@@ -1975,6 +2000,25 @@ const char *setup_git_directory_gently(int *nongit_ok)
setenv(GIT_PREFIX_ENVIRONMENT, "", 1);
}
+ /*
+ * The env variable should override the repository config
+ * for 'extensions.refStorage'.
+ */
+ ref_backend_uri = getenv(GIT_REFERENCE_BACKEND_ENVIRONMENT);
+ if (ref_backend_uri) {
+ char *backend, *payload;
+ enum ref_storage_format format;
+
+ parse_reference_uri(ref_backend_uri, &backend, &payload);
+ format = ref_storage_format_by_name(backend);
+ if (format == REF_STORAGE_FORMAT_UNKNOWN)
+ die(_("unknown ref storage format: '%s'"), backend);
+ repo_set_ref_storage_format(the_repository, format, payload);
+
+ free(backend);
+ free(payload);
+ }
+
setup_original_cwd();
strbuf_release(&dir);
@@ -2046,7 +2090,8 @@ void check_repository_format(struct repository_format *fmt)
repo_set_hash_algo(the_repository, fmt->hash_algo);
repo_set_compat_hash_algo(the_repository, fmt->compat_hash_algo);
repo_set_ref_storage_format(the_repository,
- fmt->ref_storage_format);
+ fmt->ref_storage_format,
+ fmt->ref_storage_payload);
the_repository->repository_format_worktree_config =
fmt->worktree_config;
the_repository->repository_format_submodule_path_cfg =
@@ -2319,7 +2364,8 @@ void initialize_repository_version(int hash_algo,
* the remote repository's format.
*/
if (hash_algo != GIT_HASH_SHA1_LEGACY ||
- ref_storage_format != REF_STORAGE_FORMAT_FILES)
+ ref_storage_format != REF_STORAGE_FORMAT_FILES ||
+ the_repository->ref_storage_payload)
target_version = GIT_REPO_VERSION_READ;
if (hash_algo != GIT_HASH_SHA1_LEGACY && hash_algo != GIT_HASH_UNKNOWN)
@@ -2328,11 +2374,20 @@ void initialize_repository_version(int hash_algo,
else if (reinit)
repo_config_set_gently(the_repository, "extensions.objectformat", NULL);
- if (ref_storage_format != REF_STORAGE_FORMAT_FILES)
+ if (the_repository->ref_storage_payload) {
+ struct strbuf ref_uri = STRBUF_INIT;
+
+ strbuf_addf(&ref_uri, "%s://%s",
+ ref_storage_format_to_name(ref_storage_format),
+ the_repository->ref_storage_payload);
+ repo_config_set(the_repository, "extensions.refstorage", ref_uri.buf);
+ strbuf_release(&ref_uri);
+ } else if (ref_storage_format != REF_STORAGE_FORMAT_FILES) {
repo_config_set(the_repository, "extensions.refstorage",
ref_storage_format_to_name(ref_storage_format));
- else if (reinit)
+ } else if (reinit) {
repo_config_set_gently(the_repository, "extensions.refstorage", NULL);
+ }
if (reinit) {
struct strbuf config = STRBUF_INIT;
@@ -2375,14 +2430,12 @@ static int is_reinit(void)
return ret;
}
-void create_reference_database(enum ref_storage_format ref_storage_format,
- const char *initial_branch, int quiet)
+void create_reference_database(const char *initial_branch, int quiet)
{
struct strbuf err = STRBUF_INIT;
char *to_free = NULL;
int reinit = is_reinit();
- repo_set_ref_storage_format(the_repository, ref_storage_format);
if (ref_store_create_on_disk(get_main_ref_store(the_repository), 0, &err))
die("failed to set up refs db: %s", err.buf);
@@ -2616,6 +2669,7 @@ static void repository_format_configure(struct repository_format *repo_fmt,
.ignore_repo = 1,
.ignore_worktree = 1,
};
+ const char *ref_backend_uri;
const char *env;
config_with_options(read_default_format_config, &cfg, NULL, NULL, &opts);
@@ -2661,7 +2715,26 @@ static void repository_format_configure(struct repository_format *repo_fmt,
} else {
repo_fmt->ref_storage_format = REF_STORAGE_FORMAT_DEFAULT;
}
- repo_set_ref_storage_format(the_repository, repo_fmt->ref_storage_format);
+
+
+ ref_backend_uri = getenv(GIT_REFERENCE_BACKEND_ENVIRONMENT);
+ if (ref_backend_uri) {
+ char *backend, *payload;
+ enum ref_storage_format format;
+
+ parse_reference_uri(ref_backend_uri, &backend, &payload);
+ format = ref_storage_format_by_name(backend);
+ if (format == REF_STORAGE_FORMAT_UNKNOWN)
+ die(_("unknown ref storage format: '%s'"), backend);
+
+ repo_fmt->ref_storage_format = format;
+ repo_fmt->ref_storage_payload = payload;
+
+ free(backend);
+ }
+
+ repo_set_ref_storage_format(the_repository, repo_fmt->ref_storage_format,
+ repo_fmt->ref_storage_payload);
}
int init_db(const char *git_dir, const char *real_git_dir,
@@ -2717,8 +2790,7 @@ int init_db(const char *git_dir, const char *real_git_dir,
&repo_fmt, init_shared_repository);
if (!(flags & INIT_DB_SKIP_REFDB))
- create_reference_database(repo_fmt.ref_storage_format,
- initial_branch, flags & INIT_DB_QUIET);
+ create_reference_database(initial_branch, flags & INIT_DB_QUIET);
create_object_directory();
if (repo_settings_get_shared_repository(the_repository)) {