[PATCH 06/16] Look up refs in namespace with cgit_get_sha1

Richard richard.maw at gmail.com
Sat Jul 30 17:21:03 CEST 2016

On 29 July 2016 at 17:54, Richard <richard.maw at gmail.com> wrote:
> On 29 July 2016 at 16:34, Richard <richard.maw at gmail.com> wrote:
>> I'll have a go. I don't know how successful adding a feature for a
>> different project would be.
> After I've worked out how to add the support to libgit I'll know better,
> but it might be a good idea to:
> 1.  Make a patch to add support to libgit
> 2.  Port that patch into cgit,
>     so when the libgit patch is submitted I can point to cgit
>     to say that we're using cgit as a proving ground for the change.
> 3.  Submit namespace support patch to libgit.
> 4.  When there's a release with namespace support,
>     update to it and remove the patch from cgit.
> I'm not sure whether it would be better to transplant that part of
> libgit into cgit,
> or to patch libgit at build time.

At a first approximation, the change needed is to make everything that
interacts with the files backend have a namespace aware variant,
then make these variants the ones that get called when we are using a namespace.

There is prior-art for this in the initial namespaces implementation,
which only added a for_each_ref equivalent,
which calls do_for_each_ref with a namespaced ref prefix.

The first issue with this is that the full set of operations is:

resolve_gitlink_ref, read_raw_ref, peel_ref, verify_refname_available,
rename_ref, delete_refs, ref_transaction_commit, initial_ref_transaction_commit,
create_symref, set_worktree_head_symref,
reflog_exists, for_each_reflog_ent_reverse, for_each_reflog_ent,
safe_create_reflog, files_log_ref_write, delete_reflog and reflog_expire.

pack_refs is the only one of those functions that wouldn't need to be
made namespace aware.
So to start with there's approximately 90 call-sites that would need
to be made namespace aware.

We can cull that further by only considering the interfaces for reading refs:

resolve_gitlink_ref, read_raw_ref, peel_ref, verify_refname_available,
reflog_exists, for_each_reflog_ent_reverse, for_each_reflog_ent,

This makes it about 50 call sites.

We would then need to work backwards from these functions to the APIs
we want to call (which is likely to be a significant fraction of
libgit) and add a way to thread through the call chains that we want
to opt into using the current namespace.

We would need to make some new command-line programs namespace aware,
otherwise git upstream would have no reason to accept the patches,
and we'd need to thread the flag for using the current namespace all
the way to the command-line,
rather than just detecting whether GIT_NAMESPACE was set,
since hook scripts are called with GIT_NAMESPACE set if it was set for

The age file script that was updated in this patch series would stop working
if git for-each-ref suddenly started to only handle refs in
GIT_NAMESPACE without an opt-in.

If we were to instead drop support for short branch names in the CGit API,
or continue to use our simpler dwim_ref implementation,
the only function that needs to be made namespace aware is resolve_ref_unsafe,
which we are currently handling by wrapping it with something that
translates the ref names back and forth.

In summary, I failed to find a nice way to add namespace support,
looking both top-down from the API and bottom-up from how it reads refs.
It would be a huge undertaking which reduces the odds of it being
accepted upstream,
but in doing this analysis I'm more sure that the work that's already
been submitted to cgit
is the smallest change necessary to support namespaced ref lookups.

Therefore I suggest it is best to stick with the current approach,
and the next version I submit would mark which functions should be revisited
if git gained greater support for namespaced ref resolution.
If this is a sticking point then I will attempt to make the changes in libgit,
but am uncertain whether it would be successful.

More information about the CGit mailing list