From: Patrick Steinhardt Date: Mon, 09 Feb 2026 16:34:27 GMT Subject: Re: [PATCH v5 3/4] refs: allow reference location in refstorage config Message-ID: In-Reply-To: <20260209-kn-alternate-ref-dir-v5-3-740899834ceb@gmail.com> 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. > 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/'. s/worktress/worktrees/ > 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 > +# is the relative path to the repo to run the command in. > +# is the original ref storage of the repo. > +# is the new URI to be set for the ref storage. > +# 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 > +# is the relative path to the repo to run the command in. > +# is the original ref storage of the repo. > +# is the new URI to be set for the ref storage. > +# (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? > + 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 :) > + 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