git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 2/2] refs: add GIT_REF_URI to specify reference backend and directory

From
Karthik Nayak <karthik.188@gmail.com>
Date
Nov 27, 2025, 14:52 UTC
Message-ID
<CAOLa=ZRPYUJu4hVuZrXdJ1vq89=Pkiyw0-As=0B6pL1-cymR8w@mail.gmail.com>
In-Reply-To
<xmqq7bvcpy35.fsf@gitster.g>
Junio C Hamano <gitster@pobox.com> writes:
Show 15 quoted lines
> Karthik Nayak <karthik.188@gmail.com> writes:
>
>> +`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.
>
> It is more like "<directory>" that specifies the local directory the
> backend is told to use to store its data.  It feels way too broad
> for what the initial implementation achieves and what the design can
> potentially include, to say "URI-for-resource", I would think.
>

Well I'm okay either ways, my first version was very specific as it mention '<path>'. I changed it based on the discussion with you and Toon about how the '<path>' is the URI for the reference backend.

Show 39 quoted lines
>> 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..a7af228799 100644
>> --- a/refs.c
>> +++ b/refs.c
>> @@ -2186,15 +2186,73 @@ 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 || !uri[0]) {
>> +		error("reference backend uri is empty");
>> +		goto cleanup;
>> +	}
>
> Equating !uri and !uri[0] and giving the same message would not help
> diagnosing an error, and not _("localizing") the message is of dubious
> value (after all, the message is not being given to somebody coming
> over the network, but meant to be given to the local user, right?).
>

I think that's fair. I also missed localizing all the errors, I think someone did point that out too.

> If we remove the !uri[0] from the check, shouldn't the later check
> catch it as "invalid format" anyway, and print '%s' it to show that
> what was given was empty clearly enough?
>
Yeah, it should I'll remove the latter and modify the test.
Show 16 quoted lines
>> +	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;
>
> Two questions.  (1) do we still want the double-slash after the
> colon?  (2) if so, would it make it simpler to string-list-split
> using "://" as the separator?
>

(1) Yes. (2) My understanding of `string_list_split()` was that the `delim` argument are a set of characters to split the string on.

So:
    string_list_split(l, "abc:def/ghi/jkl", "://", -1) -> ["abc",
"def", "ghi", "jkl"]
    string_list_split(l, "reftable://foo", "://", -1) -> ["reftable",
"", "", "foo", "bar"]
But this isn't what we want.
Show 7 quoted lines
>> +	format_string = ref_backend_info.items[0].string;
>> +	dir = ref_backend_info.items[1].string + 2;
>
> These two lines are fishy.  Perhaps leftover from an earlier draft
> that did not have an error checking before the previous 5 lines were
> added?
>
Yes, will cleanup.
Show 12 quoted lines
>> +	if (!dir || !dir[0]) {
>> +		error("invalid path in uri '%s'", uri);
>> +		goto cleanup;
>> +	}
>
> At this point it is very unlikely for "dir" to be NULL, no?  Even if
> the .string member after splitting were NULL, adding 2 to it would
> not leave it NULL.
>
> Being defensive and checking for NULL is good, but then exactly the
> same question on "NULL vs an empty string" applies here.
>
Yea, the '!dir[0]' should definitely be enough here.
Show 30 quoted lines
>>  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;
>>  }
>
> If this mechanism is for consumption by "git refs migrate", is it
> possible to reduce the blast radius by giving the command a command
> line option to do an equivalent of this?  I really am not happy with
> this environment variable that can change the behaviour of such a
> low level layer from unsuspecting programs that are not ready.
>

But the mechanism isn't for 'git refs migrate', but rather we want to add/update references via 'git update-ref' into the dry-run folder created by the 'git refs migrate'. In the broader sense, we want to manipulate references within this dry-run folder as if it is the reference folder for the underlying repository.

I get the comprehension behind the environment variable and am happy to work on something alternative if we can achieve something similar. The reason to pick the ENV variable was mostly because this isn't a regular user flag which we expect users to use. Also, this is very similar to the already existing GIT_OBJECT_DIRECTORY.

Show 8 quoted lines
> Instead of tweaking the behaviour of this function via environment
> that can affect any programs, can't we give these callers like "git
> refs migrate" with specific needs set_main_ref_store() function that
> takes a ref_store and a repository.  Then they can use to call into
> get_ref_store_for_dir() to obtain a ref they need.  "git refs migrate"
> already takes "--ref-format" variable, so all it needs is another
> "--ref-directory" command line option, right?
>

Something like this would require us to add these flags to all commands, currently I can think of 'git update-ref' and 'git refs' but it could spread to all reference oriented commands.

Show 8 quoted lines
> If the ability to set the ref backend location for arbitrary program
> proves to be useful, we _could_ give the same --ref-format and
> --ref-direcctory command line options to "git" itself (like "git -C
> there" runs any subcommand in the named directory), which does the
> the get_ref_store_for_dir() plus set_main_ref_store() dance,
> modelled after how "git refs migrate" does them.
>
> Hmm?

This could work indeed, I would instead swap it out for a single "--ref-uri=<backend>://<uri>" which would make it much simpler for users and future implementations which might not have a 'directory' like the current backends do.

Overall the ENV variable seemed the best based on the constraints and the existing similar variables. Wdyt?

Previous: Junio C HamanoNext: Junio C Hamano
Message 6 of 8 in “refs: allow setting the reference directory”
  1. 0/2 refs: allow setting the reference directoryKarthik Nayak, Nov 26, 2025
  2. 1/2 refs: support obtaining ref_store for given dirKarthik Nayak, Nov 26, 2025
  3. Junio C HamanoNov 26, 2025
  4. 2/2 refs: add GIT_REF_URI to specify reference backend and directoryKarthik Nayak, Nov 26, 2025
  5. Junio C HamanoNov 26, 2025
  6. Karthik NayakNov 27, 2025
  7. Junio C HamanoNov 27, 2025
  8. Karthik NayakNov 27, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.