Re: [PATCH v5 3/4] refs: allow reference location in refstorage config
- From
Patrick Steinhardt <ps@pks.im>
- Date
- Feb 9, 2026, 16:34 UTC
- Message-ID
- <aYoMk5HmpSyN1azt@pks.im>
- 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:
Show 12 quoted lines
> 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.
Show 10 quoted lines
> 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/
Show 92 quoted lines
> 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?
Show 12 quoted lines
> + 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