Re: [PATCH v5 3/4] refs: allow reference location in refstorage config
From: Patrick Steinhardt <hidden>
Date: 2026-02-09 16:34:32
On Mon, Feb 09, 2026 at 04:58:20PM +0100, Karthik Nayak wrote:
The 'extensions.refStorage' config is used to specify the reference backend for a given repository. Both the 'files' and 'reftable' backends utilize the $GIT_DIR as the reference folder by default in `get_main_ref_store()`. Since the reference backends are pluggable, this means that they could work with out-of-tree reference directories too. Extend the 'refStorage' config to also support taking an URI input, where users can specify the reference backend and the location. Add the required changes to obtain and propagate this value to the individual backends also add the necessary documentation and tests.
This reads as if this should have been two sentences.
quoted hunk ↗ jump to hunk
diff --git a/builtin/worktree.c b/builtin/worktree.c index fbdaf2eb2e..94480be5c4 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c@@ -425,6 +425,39 @@ static int make_worktree_orphan(const char * ref, const struct add_opts *opts, return run_command(&cp); } +/* + * References for worktress are generally stored in '$GIT_DIR/worktrees/<wt_id>'.
s/worktress/worktrees/
quoted hunk ↗ jump to hunk
diff --git a/t/t1423-ref-backend.sh b/t/t1423-ref-backend.sh new file mode 100755 index 0000000000..9c777b79f3 --- /dev/null +++ b/t/t1423-ref-backend.sh@@ -0,0 +1,159 @@ +#!/bin/sh + +test_description='Test reference backend URIs' + +. ./test-lib.sh + +# Run a git command with the provided reference storage. Reset the backend +# post running the command. +# Usage: run_with_uri <repo> <backend> <uri> <cmd> +# <repo> is the relative path to the repo to run the command in. +# <backend> is the original ref storage of the repo. +# <uri> is the new URI to be set for the ref storage. +# <cmd> is the git subcommand to be run in the repository. +run_with_uri() { + repo=$1 && + backend=$2 && + uri=$3 && + cmd=$4 && + + git -C "$repo" config set core.repositoryformatversion 1 + git -C "$repo" config set extensions.refStorage "$uri" && + git -C "$repo" $cmd && + git -C "$repo" config set extensions.refStorage "$backend" +} + +# Test a repository with a given reference storage by running and comparing +# 'git refs list' before and after setting the new reference backend. If +# err_msg is set, expect the command to fail and grep for the provided err_msg. +# Usage: run_with_uri <repo> <backend> <uri> <cmd> +# <repo> is the relative path to the repo to run the command in. +# <backend> is the original ref storage of the repo. +# <uri> is the new URI to be set for the ref storage. +# <err_msg> (optional) if set, check if 'git-refs(1)' failed with the provided msg. +test_refs_backend() { + repo=$1 && + backend=$2 && + uri=$3 && + err_msg=$4 && + + git -C "$repo" config set core.repositoryformatversion 1 && + if test -n "$err_msg"; + then + git -C "$repo" config set extensions.refStorage "$uri" && + test_must_fail git -C "$repo" refs list 2>err && + test_grep "$err_msg" err + else + git -C "$repo" refs list >expect && + run_with_uri "$repo" "$backend" "$uri" "refs list" >actual && + test_cmp expect actual + fi +} + +test_expect_success 'URI is invalid' ' + test_when_finished "rm -rf repo" && + git init repo && + test_refs_backend repo files "reftable@/home/reftable" \ + "invalid value for ${SQ}extensions.refstorage${SQ}" +' + +test_expect_success 'URI ends with colon' ' + test_when_finished "rm -rf repo" && + git init repo && + test_refs_backend repo files "reftable:" \ + "invalid value for ${SQ}extensions.refstorage${SQ}" +' + +test_expect_success 'unknown reference backend' ' + test_when_finished "rm -rf repo" && + git init repo && + test_refs_backend repo files "db://.git" \ + "invalid value for ${SQ}extensions.refstorage${SQ}" +' + +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 + + + for dir in "$(pwd)/repo/.git" "./"
As "./" is a relative directory I expect it to be resolved relative to "$GIT_DIR", right? Also, I don't see any tests that create the ref directory outside of the repository. Should we maybe add one?
quoted hunk ↗ jump to hunk
+ do + + test_expect_success "$read from $to_format backend, $dir dir" ' + 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 &&
Okay, we do the migration, but with "--dry-run". This should result in a temporary staging directory, which is in fact somewhat interesting given that "to_format" can now contain a payload. I assume it wouldn't have an impact if such a payload was set here?
+ BACKEND_PATH="$dir/$(sed "s/.* ${SQ}.git\/\(.*\)${SQ}/\1/" out)" &&Hm. I have no idea what this is doing :)
quoted hunk ↗ jump to hunk
+ test_refs_backend . $from_format "$to_format://$BACKEND_PATH" "$method" + ) + '
In general I think it would be sensible to also have a couple tests here
that exercise specific formats directly. Like:
- Are the files created in the right spots for the files and reftable
backend with a specific backend?
- Does `git refs migrate` know to write the files into the correct
location in case "--dry-run" wasn't passed?
- Does git-init(1) and git-clone(1) initialize the refstore in a
different location as expected?
- Does creating a worktree work?
Patrick