Subject: Re: [PATCH] Allow to control the namespace for replace refs

From: Junio C Hamano <[email-masked]>
Date: Wed, 10 Jun 2015 21:55:30 -0700

Mike Hommey <[email-masked]> writes:

> It can be useful to have grafts or replace refs for specific use-cases while
> keeping the default "view" of the repository pristine (or with a different
> set of grafts/replace refs).
>
> It is possible to use a different graft file with GIT_GRAFT_FILE, but while
> replace refs are more powerful, they don't have an equivalent override.
>
> Add a GIT_REPLACE_NAMESPACE environment variable to control where git is
> going to look for replace refs.
>
> Signed-off-by: Mike Hommey <[email-masked]>
> ---
>
> I'm not sure if I need to care about avoiding strlen in log-tree.c, or if I
> should handle the lack of a / at the end of GIT_REPLACE_NAMESPACE.

First, let me agree with you that being able to say "I usually use
refs/replace/ hierarchy as my object replacement database, but for
this particular invocation of Git (or 'all Git invocations from this
subprocess' for that matter), I want to use refs/replace-2/ hierarchy
instead" is a good thing.

I however doubt that it is a good idea to use the word "namespace"
anywhere in the name for that mechanism.  Let me explain, and please
listen with skepticism, as I do not use the ref namespace mechanism
myself---it is entirely possible that my understanding of how the
ref namespace mechanism is meant to be used is faulty, and if that
is the case please correct me.

The ref namespace mechanism is to be used when you want to serve one
or more "virtual repositories" via upload-pack/receive-pack server
side programs from a single repository.  By having two hierarchies,
each of which is similar to the usual HEAD, refs/heads/, refs/tags/,
etc., under refs/namespaces/a and refs/namespaces/b, you can allow
two instances of upload-pack to serve two "virtual repositories".

What is in refs/namespaces/a/{HEAD,refs/heads/*,refs/tags/*,...} is
exposed by one instance of upload-pack to its clients as if they are
the entire world (i.e. HEAD,refs/heads/*,refs/tags/*,...), the other
one does the same to its clients from refs/namespaces/b/*.  And they
do share the same object store (thereby allowing you to implement a
cheap "forks" without having to worry about object borrowing).

The usual server side housekeeping such as "gc" can and must be
arranged to happen without limiting them to either namespace, so
that anything reachable by any ref from either "virtual repository"
will be retained.

Now, does the "For this invocation, please use refs/replace-2/ as
the object replacement database" feature have anything common to the
ref namespace mechanism?  I do not see any commonality, and that is
why I do not think it is a good idea to use that word.  It will
confuse the users and the developers alike.

To me, this mechanism looks very similar to the way you specify a
non-default notes tree is to be used with the --notes=<ref>
parameter, core.notesRef configuration and GIT_NOTES_REF environment
variable.  Modeling after that, perhaps using core.replaceRef and
GIT_REPLACE_REF would be more appropriate, I think.

Thanks.