diff options
| author | Karthik Nayak <karthik.188@gmail.com> | 2026-02-25 10:40:46 +0100 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2026-02-25 09:40:00 -0800 |
| commit | 53592d68e86814fcc4a8df6cc38340597e56fe5a (patch) | |
| tree | ba40af5ae430ea79abd4f1898562c736f4f408b9 /setup.c | |
| parent | 01dc84594ee365ee7086fccc7f590ab527730531 (diff) | |
| download | git-53592d68e86814fcc4a8df6cc38340597e56fe5a.tar.xz | |
refs: add GIT_REFERENCE_BACKEND to specify reference backend
Git allows setting a different object directory via
'GIT_OBJECT_DIRECTORY', but provides no equivalent for references. In
the previous commit we extended the 'extensions.refStorage' config to
also support an URI input for reference backend with location.
Let's also add a new environment variable 'GIT_REFERENCE_BACKEND' that
takes in the same input as the config variable. Having an environment
variable allows us to modify the reference backend and location on the
fly for individual Git commands.
The environment variable also allows usage of alternate reference
directories during 'git-clone(1)' and 'git-init(1)'. Add the config to
the repository when created with the environment variable set.
When initializing the repository with an alternate reference folder,
create the required stubs in the repositories $GIT_DIR. The inverse,
i.e. removal of the ref store doesn't clean up the stubs in the $GIT_DIR
since that would render it unusable. Removal of ref store is only used
when migrating between ref formats and cleanup of the $GIT_DIR doesn't
make sense in such a situation.
Helped-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'setup.c')
| -rw-r--r-- | setup.c | 55 |
1 files changed, 52 insertions, 3 deletions
@@ -1838,6 +1838,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; /* @@ -1995,6 +1996,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); @@ -2337,7 +2357,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) @@ -2346,11 +2367,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; @@ -2623,6 +2653,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); @@ -2668,6 +2699,24 @@ static void repository_format_configure(struct repository_format *repo_fmt, } else { repo_fmt->ref_storage_format = REF_STORAGE_FORMAT_DEFAULT; } + + + 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); } |
