public inbox for git@vger.kernel.org 
 help / color / mirror / Atom feed
From: Karthik Nayak <karthik.188@gmail•com>
To: git@vger•kernel.org
Cc: jltobler@gmail•com, gitster@pobox•com, toon@iotcl•com,
	sunshine@sunshineco•com, "Jean-Noël Avila" <jn.avila@free•fr>,
	"Karthik Nayak" <karthik.188@gmail•com>
Subject: [PATCH v3 2/2] refs: add GIT_REF_URI to specify reference backend and directory
Date: Mon, 01 Dec 2025 12:24:59 +0100	[thread overview]
Message-ID: <20251201-kn-alternate-ref-dir-v3-2-c11b946bc2fa@gmail.com> (raw)
In-Reply-To: <20251201-kn-alternate-ref-dir-v3-0-c11b946bc2fa@gmail.com>

Git allows setting a different object directory via
'GIT_OBJECT_DIRECTORY', but provides no equivalent for references.
This asymmetry makes it difficult to test different reference backends
or use alternative reference storage locations without modifying the
repository structure.

Add a new environment variable 'GIT_REF_URI' that specifies both the
reference backend and directory path using a URI format:

    <ref_backend>://<URI-for-resource>

When set, this variable is used to obtain the main reference store for
all Git commands. The variable is checked in `get_main_ref_store()`
when lazily assigning `repo->refs_private`. We cannot initialize this
earlier in `repo_set_gitdir()` because the repository's hash algorithm
isn't known at that point, and the reftable backend requires this
information during initialization.

When used with worktrees, the specified directory is treated as the
reference directory for all worktree operations.

Add a new test file 't1423-ref-backend.sh' to test this environment
variable.

Helped-by: Jean-Noël Avila <jn.avila@free•fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail•com>
---
 Documentation/git.adoc |   8 ++++
 environment.h          |   1 +
 refs.c                 |  57 ++++++++++++++++++++++-
 t/meson.build          |   1 +
 t/t1423-ref-backend.sh | 121 +++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 187 insertions(+), 1 deletion(-)

diff --git a/Documentation/git.adoc b/Documentation/git.adoc
index ce099e78b8..8c6a3f6042 100644
--- a/Documentation/git.adoc
+++ b/Documentation/git.adoc
@@ -584,6 +584,14 @@ double-quotes and respecting backslash escapes. E.g., the value
 	repositories will be set to this value. The default is "files".
 	See `--ref-format` in linkgit:git-init[1].
 
+`GIT_REF_URI`::
+    Specify which reference backend to be used along with its URI. Reference
+    backends like the files, reftable backend use the $GIT_DIR as their URI.
++
+Expects the format `<ref_backend>://<URI-for-resource>`, where the
+_<ref_backend>_ specifies the reference backend and the _<URI-for-resource>_
+specifies the URI used by the backend.
+
 Git Commits
 ~~~~~~~~~~~
 `GIT_AUTHOR_NAME`::
diff --git a/environment.h b/environment.h
index 51898c99cd..9bc380bba4 100644
--- a/environment.h
+++ b/environment.h
@@ -42,6 +42,7 @@
 #define GIT_OPTIONAL_LOCKS_ENVIRONMENT "GIT_OPTIONAL_LOCKS"
 #define GIT_TEXT_DOMAIN_DIR_ENVIRONMENT "GIT_TEXTDOMAINDIR"
 #define GIT_ATTR_SOURCE_ENVIRONMENT "GIT_ATTR_SOURCE"
+#define GIT_REF_URI_ENVIRONMENT "GIT_REF_URI"
 
 /*
  * Environment variable used to propagate the --no-advice global option to the
diff --git a/refs.c b/refs.c
index 23f46867f2..da76e0c54a 100644
--- a/refs.c
+++ b/refs.c
@@ -2186,15 +2186,70 @@ static struct ref_store *get_ref_store_for_dir(struct repository *r,
 	return maybe_debug_wrap_ref_store(dir, ref_store);
 }
 
+static struct ref_store *get_ref_store_from_uri(struct repository *repo,
+						const char *uri)
+{
+	struct string_list ref_backend_info = STRING_LIST_INIT_DUP;
+	enum ref_storage_format format;
+	struct ref_store *store = NULL;
+	char *format_string;
+	char *dir;
+
+	if (!uri) {
+		error(_("reference backend uri is not provided"));
+		goto cleanup;
+	}
+
+	if (string_list_split(&ref_backend_info, uri, ":", 2) != 2) {
+		error(_("invalid reference backend uri format '%s'"), uri);
+		goto cleanup;
+	}
+
+	format_string = ref_backend_info.items[0].string;
+	if (!starts_with(ref_backend_info.items[1].string, "//")) {
+		error(_("invalid reference backend uri format '%s'"), uri);
+		goto cleanup;
+	}
+	dir = ref_backend_info.items[1].string + 2;
+
+	if (!dir[0]) {
+		error(_("invalid path in uri '%s'"), uri);
+		goto cleanup;
+	}
+
+	format = ref_storage_format_by_name(format_string);
+	if (format == REF_STORAGE_FORMAT_UNKNOWN) {
+		error(_("unknown reference backend '%s'"), format_string);
+		goto cleanup;
+	}
+
+	store = get_ref_store_for_dir(repo, dir, format);
+
+cleanup:
+	string_list_clear(&ref_backend_info, 0);
+	return store;
+}
+
 struct ref_store *get_main_ref_store(struct repository *r)
 {
+	char *ref_uri;
+
 	if (r->refs_private)
 		return r->refs_private;
 
 	if (!r->gitdir)
 		BUG("attempting to get main_ref_store outside of repository");
 
-	r->refs_private = get_ref_store_for_dir(r, r->gitdir, r->ref_storage_format);
+	ref_uri = getenv(GIT_REF_URI_ENVIRONMENT);
+	if (ref_uri) {
+		r->refs_private = get_ref_store_from_uri(r, ref_uri);
+		if (!r->refs_private)
+			die("failed to initialize ref store from URI: %s", ref_uri);
+
+	} else {
+		r->refs_private = get_ref_store_for_dir(r, r->gitdir,
+							r->ref_storage_format);
+	}
 	return r->refs_private;
 }
 
diff --git a/t/meson.build b/t/meson.build
index a5531df415..a66f8fafff 100644
--- a/t/meson.build
+++ b/t/meson.build
@@ -208,6 +208,7 @@ integration_tests = [
   't1420-lost-found.sh',
   't1421-reflog-write.sh',
   't1422-show-ref-exists.sh',
+  't1423-ref-backend.sh',
   't1430-bad-ref-name.sh',
   't1450-fsck.sh',
   't1451-fsck-buffer.sh',
diff --git a/t/t1423-ref-backend.sh b/t/t1423-ref-backend.sh
new file mode 100755
index 0000000000..f36125bf64
--- /dev/null
+++ b/t/t1423-ref-backend.sh
@@ -0,0 +1,121 @@
+#!/bin/sh
+
+test_description='Test different reference backend URIs'
+
+. ./test-lib.sh
+
+test_expect_success 'empty uri provided' '
+	test_when_finished "rm -rf repo" &&
+	git init --ref-format=files repo &&
+	(
+		cd repo &&
+		GIT_REF_URI="" &&
+		export GIT_REF_URI &&
+		test_must_fail git refs list 2>err &&
+		test_grep "invalid reference backend uri format" err
+	)
+'
+
+test_expect_success 'invalid uri provided' '
+	test_when_finished "rm -rf repo" &&
+	git init --ref-format=files repo &&
+	(
+		cd repo &&
+		GIT_REF_URI="reftable@/home/reftable" &&
+		export GIT_REF_URI &&
+		test_must_fail git refs list 2>err &&
+		test_grep "invalid reference backend uri format" err
+	)
+'
+
+test_expect_success 'empty path in uri' '
+	test_when_finished "rm -rf repo" &&
+	git init --ref-format=files repo &&
+	(
+		cd repo &&
+		GIT_REF_URI="reftable://" &&
+		export GIT_REF_URI &&
+		test_must_fail git refs list 2>err &&
+		test_grep "invalid path in uri" err
+	)
+'
+
+test_expect_success 'uri ends at colon' '
+	test_when_finished "rm -rf repo" &&
+	git init --ref-format=files repo &&
+	(
+		cd repo &&
+		GIT_REF_URI="reftable:" &&
+		export GIT_REF_URI &&
+		test_must_fail git refs list 2>err &&
+		test_grep "invalid reference backend uri format" err
+	)
+'
+
+test_expect_success 'unknown reference backend' '
+	test_when_finished "rm -rf repo" &&
+	git init --ref-format=files repo &&
+	(
+		cd repo &&
+		GIT_REF_URI="db://.git" &&
+		export GIT_REF_URI &&
+		test_must_fail git refs list 2>err &&
+		test_grep "unknown reference backend" err
+	)
+'
+
+ref_formats="files reftable"
+for from_format in $ref_formats
+do
+	for to_format in $ref_formats
+	do
+		if test "$from_format" = "$to_format"
+		then
+			continue
+		fi
+
+		test_expect_success "read from $to_format backend" '
+			test_when_finished "rm -rf repo" &&
+			git init --ref-format=$from_format repo &&
+			(
+				cd repo &&
+				test_commit 1 &&
+				test_commit 2 &&
+				test_commit 3 &&
+
+				git refs migrate --dry-run --ref-format=$to_format >out &&
+				BACKEND_PATH=$(cat out | sed "s/.* ${SQ}\(.*\)${SQ}/\1/") &&
+				git refs list >expect &&
+				GIT_REF_URI="$to_format://$BACKEND_PATH" git refs list >actual &&
+				test_cmp expect actual
+			)
+		'
+
+		test_expect_success "write to $to_format backend" '
+			test_when_finished "rm -rf repo" &&
+			git init --ref-format=$from_format repo &&
+			(
+				cd repo &&
+				test_commit 1 &&
+				test_commit 2 &&
+				test_commit 3 &&
+
+				git refs migrate --dry-run --ref-format=$to_format >out &&
+				git refs list >expect &&
+
+				BACKEND_PATH=$(cat out | sed "s/.* ${SQ}\(.*\)${SQ}/\1/") &&
+				GIT_REF_URI="$to_format://$BACKEND_PATH" git tag -d 1 &&
+
+				git refs list >actual &&
+				test_cmp expect actual &&
+
+				GIT_REF_URI="$to_format://$BACKEND_PATH" git refs list >expect &&
+				git refs list >out &&
+				cat out | grep -v "refs/tags/1" >actual &&
+				test_cmp expect actual
+			)
+		'
+	done
+done
+
+test_done

-- 
2.51.2


  parent reply	other threads:[~2025-12-01 11:25 UTC|newest]

Thread overview: 131+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-19 21:48 [PATCH 0/2] refs: allow setting the reference directory Karthik Nayak
2025-11-19 21:48 ` [PATCH 1/2] refs: support obtaining ref_store for given dir Karthik Nayak
2025-11-20 19:05   ` Justin Tobler
2025-11-21 11:18     ` Karthik Nayak
2025-11-19 21:48 ` [PATCH 2/2] refs: add GIT_REF_URI to specify reference backend and directory Karthik Nayak
2025-11-19 22:13   ` Eric Sunshine
2025-11-19 23:01     ` Karthik Nayak
2025-11-20 10:00   ` Jean-Noël Avila
2025-11-21 11:21     ` Karthik Nayak
2025-11-20 19:38   ` Justin Tobler
2025-11-24 13:23     ` Karthik Nayak
2025-11-21 13:42   ` Toon Claes
2025-11-21 16:07     ` Junio C Hamano
2025-11-24 13:25       ` Karthik Nayak
2025-11-26 13:11         ` Toon Claes
2025-11-24 13:26     ` Karthik Nayak
2025-12-01 13:28   ` Patrick Steinhardt
2025-12-02 22:21     ` Karthik Nayak
2025-11-23  4:29 ` [PATCH 0/2] refs: allow setting the reference directory Junio C Hamano
2025-12-01 13:19   ` Patrick Steinhardt
2025-12-02 10:25     ` Junio C Hamano
2025-12-02 15:29     ` Karthik Nayak
2025-11-26 11:11 ` [PATCH v2 " Karthik Nayak
2025-11-26 11:12   ` [PATCH v2 1/2] refs: support obtaining ref_store for given dir Karthik Nayak
2025-11-26 15:16     ` Junio C Hamano
2025-11-26 11:12   ` [PATCH v2 2/2] refs: add GIT_REF_URI to specify reference backend and directory Karthik Nayak
2025-11-26 16:17     ` Junio C Hamano
2025-11-27 14:52       ` Karthik Nayak
2025-11-27 20:02         ` Junio C Hamano
2025-11-27 21:45           ` Karthik Nayak
2025-12-01 11:24 ` [PATCH v3 0/2] refs: allow setting the reference directory Karthik Nayak
2025-12-01 11:24   ` [PATCH v3 1/2] refs: support obtaining ref_store for given dir Karthik Nayak
2025-12-01 11:24   ` Karthik Nayak [this message]
2026-01-05 15:13   ` [PATCH v3 0/2] refs: allow setting the reference directory Patrick Steinhardt
2026-01-05 20:13     ` Karthik Nayak
2026-01-20 21:03       ` Junio C Hamano
2026-01-22 12:36         ` Karthik Nayak
2026-02-02 12:26 ` [PATCH v4 0/4] " Karthik Nayak
2026-02-02 12:26   ` [PATCH v4 1/4] refs: allow reference location in refstorage config Karthik Nayak
2026-02-06 14:33     ` Patrick Steinhardt
2026-02-09 12:25       ` Karthik Nayak
2026-02-02 12:26   ` [PATCH v4 2/4] refs: extract out `refs_create_refdir_stubs()` Karthik Nayak
2026-02-06 14:33     ` Patrick Steinhardt
2026-02-09 11:21       ` Karthik Nayak
2026-02-02 12:26   ` [PATCH v4 3/4] refs: parse and use the reference storage payload Karthik Nayak
2026-02-06 14:33     ` Patrick Steinhardt
2026-02-09 12:52       ` Karthik Nayak
2026-02-02 12:26   ` [PATCH v4 4/4] refs: add GIT_REFERENCE_BACKEND to specify reference backend Karthik Nayak
2026-02-06 14:33     ` Patrick Steinhardt
2026-02-09 12:53       ` Karthik Nayak
2026-02-06 14:33   ` [PATCH v4 0/4] refs: allow setting the reference directory Patrick Steinhardt
2026-02-06 17:50     ` Junio C Hamano
2026-02-09 12:53     ` Karthik Nayak
2026-02-09 15:58 ` [PATCH v5 " Karthik Nayak
2026-02-09 15:58   ` [PATCH v5 1/4] refs: extract out `refs_create_refdir_stubs()` Karthik Nayak
2026-02-09 15:58   ` [PATCH v5 2/4] refs: forward and use the reference storage payload Karthik Nayak
2026-02-09 16:34     ` Patrick Steinhardt
2026-02-10 10:09       ` Karthik Nayak
2026-02-10 22:46     ` Jeff King
2026-02-13 14:45       ` Karthik Nayak
2026-02-15  9:12         ` Jeff King
2026-02-09 15:58   ` [PATCH v5 3/4] refs: allow reference location in refstorage config Karthik Nayak
2026-02-09 16:34     ` Patrick Steinhardt
2026-02-10 13:02       ` Karthik Nayak
2026-02-10 22:44     ` Jeff King
2026-02-11 10:27       ` Karthik Nayak
2026-02-09 15:58   ` [PATCH v5 4/4] refs: add GIT_REFERENCE_BACKEND to specify reference backend Karthik Nayak
2026-02-09 16:34   ` [PATCH v5 0/4] refs: allow setting the reference directory Patrick Steinhardt
2026-02-09 18:02   ` Junio C Hamano
2026-02-10 13:02     ` Karthik Nayak
2026-02-10 15:35       ` Junio C Hamano
2026-02-14 22:34 ` [PATCH v6 0/6] " Karthik Nayak
2026-02-14 22:34   ` [PATCH v6 1/6] setup: don't modify repo in `create_reference_database()` Karthik Nayak
2026-02-17  7:24     ` Patrick Steinhardt
2026-02-17  9:15       ` Karthik Nayak
2026-02-14 22:34   ` [PATCH v6 2/6] refs: extract out `refs_create_refdir_stubs()` Karthik Nayak
2026-02-14 22:34   ` [PATCH v6 3/6] refs: receive and use the reference storage payload Karthik Nayak
2026-02-17  7:24     ` Patrick Steinhardt
2026-02-17  9:16       ` Karthik Nayak
2026-02-14 22:34   ` [PATCH v6 4/6] refs: move out stub modification to generic layer Karthik Nayak
2026-02-17  7:24     ` Patrick Steinhardt
2026-02-17  9:29       ` Karthik Nayak
2026-02-18 14:21         ` Toon Claes
2026-02-19  9:31           ` Karthik Nayak
2026-02-14 22:34   ` [PATCH v6 5/6] refs: allow reference location in refstorage config Karthik Nayak
2026-02-14 22:34   ` [PATCH v6 6/6] refs: add GIT_REFERENCE_BACKEND to specify reference backend Karthik Nayak
2026-02-17  7:24     ` Patrick Steinhardt
2026-02-17  9:32       ` Karthik Nayak
2026-02-17 10:15         ` Patrick Steinhardt
2026-02-18 15:27     ` Toon Claes
2026-02-19  9:35       ` Karthik Nayak
2026-02-19  9:38 ` [PATCH v7 0/6] refs: allow setting the reference directory Karthik Nayak
2026-02-19  9:38   ` [PATCH v7 1/6] setup: don't modify repo in `create_reference_database()` Karthik Nayak
2026-02-19  9:38   ` [PATCH v7 2/6] refs: extract out `refs_create_refdir_stubs()` Karthik Nayak
2026-02-19  9:38   ` [PATCH v7 3/6] refs: move out stub modification to generic layer Karthik Nayak
2026-02-20 15:21     ` Toon Claes
2026-02-19  9:38   ` [PATCH v7 4/6] refs: receive and use the reference storage payload Karthik Nayak
2026-02-20 15:32     ` Toon Claes
2026-02-22 20:12       ` Karthik Nayak
2026-02-19  9:38   ` [PATCH v7 5/6] refs: allow reference location in refstorage config Karthik Nayak
2026-02-20 15:36     ` Toon Claes
2026-02-20 16:53       ` Junio C Hamano
2026-02-22 20:15         ` Karthik Nayak
2026-02-19  9:38   ` [PATCH v7 6/6] refs: add GIT_REFERENCE_BACKEND to specify reference backend Karthik Nayak
2026-02-19 15:35     ` Patrick Steinhardt
2026-02-20  9:15       ` Karthik Nayak
2026-02-23  8:01 ` [PATCH v8 0/6] refs: allow setting the reference directory Karthik Nayak
2026-02-23  8:01   ` [PATCH v8 1/6] setup: don't modify repo in `create_reference_database()` Karthik Nayak
2026-02-23  8:01   ` [PATCH v8 2/6] refs: extract out `refs_create_refdir_stubs()` Karthik Nayak
2026-02-23  8:01   ` [PATCH v8 3/6] refs: move out stub modification to generic layer Karthik Nayak
2026-02-23  8:01   ` [PATCH v8 4/6] refs: receive and use the reference storage payload Karthik Nayak
2026-02-23  8:01   ` [PATCH v8 5/6] refs: allow reference location in refstorage config Karthik Nayak
2026-02-23 17:43     ` Kristoffer Haugsbakk
2026-02-24 13:09       ` Karthik Nayak
2026-02-24 13:20         ` Kristoffer Haugsbakk
2026-02-24 15:05           ` Karthik Nayak
2026-02-23  8:01   ` [PATCH v8 6/6] refs: add GIT_REFERENCE_BACKEND to specify reference backend Karthik Nayak
2026-02-25  8:50     ` Toon Claes
2026-02-25  9:41       ` Karthik Nayak
2026-02-23 10:54   ` [PATCH v8 0/6] refs: allow setting the reference directory Patrick Steinhardt
2026-02-23 13:37     ` Karthik Nayak
2026-02-23 20:05       ` Junio C Hamano
2026-02-25  9:42         ` Karthik Nayak
2026-02-25  9:40 ` [PATCH v9 " Karthik Nayak
2026-02-25  9:40   ` [PATCH v9 1/6] setup: don't modify repo in `create_reference_database()` Karthik Nayak
2026-02-25  9:40   ` [PATCH v9 2/6] refs: extract out `refs_create_refdir_stubs()` Karthik Nayak
2026-02-25  9:40   ` [PATCH v9 3/6] refs: move out stub modification to generic layer Karthik Nayak
2026-02-25  9:40   ` [PATCH v9 4/6] refs: receive and use the reference storage payload Karthik Nayak
2026-02-25  9:40   ` [PATCH v9 5/6] refs: allow reference location in refstorage config Karthik Nayak
2026-02-25 17:42     ` Junio C Hamano
2026-02-25  9:40   ` [PATCH v9 6/6] refs: add GIT_REFERENCE_BACKEND to specify reference backend Karthik Nayak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251201-kn-alternate-ref-dir-v3-2-c11b946bc2fa@gmail.com \
    --to=karthik.188@gmail$(echo .)com \
    --cc=git@vger$(echo .)kernel.org \
    --cc=gitster@pobox$(echo .)com \
    --cc=jltobler@gmail$(echo .)com \
    --cc=jn.avila@free$(echo .)fr \
    --cc=sunshine@sunshineco$(echo .)com \
    --cc=toon@iotcl$(echo .)com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox