Subject: Re: git gc and worktrees

From: Michael Haggerty <[email-masked]>
Date: Wed, 1 Jun 2016 18:12:51 +0200

On 06/01/2016 05:15 PM, Junio C Hamano wrote:
> Michael Haggerty <[email-masked]> writes:
> 
>> I think reference stores are going to need two distinct types of
>> reference iteration: one to iterate over the *logical* reference space
>> of a single repo or worktree, and one to find all *local* references
>> and/or reachability roots (e.g., when run within a linked repo).
> 
> This is hard reason about without defining *logical* and *local*.

By "logical" I mean the references that appear to be available in the
specified repository. Roughly, "what reference names can I pass to `git
rev-parse`?" If you are in a linked repo, your "logical" references are
most of those in the main repo plus the "HEAD" and "refs/bisect/*" and
probably a couple other pseudo-refs that are stored in your worktree.

"Local" is probably a bad name. What I mean is that we have multiple
physical places to store references. In particular, in the case of
linked repos we have the main repo's references plus we have the
worktree's local references.

Most Git commands care only about the "logical" references in the repo.
But some commands (mostly having to do with reachability) need to know
about all roots, and therefore have to know about the union of all of
the references stored in each of the linked repositories.

Note that in the second case it is a little silly even talking about
"references", because references in different linked repos might have
the same names. We're really talking about reachability roots that might
have a little metadata connected with them, like "this SHA-1 came from
reference 'HEAD' in the 'test' worktree" or "this SHA-1 came from the
reflog of 'refs/heads/master' in the main repo".

I argue that the fundamental concept in terms of the implementation
should be the individual physical reference stores, and these should be
compounded together to form the logical reference collections and the
sets of reachability roots that are interesting at the UI level.

> For protecting necessary objects from pruning by anchoring them as
> "reachable", and for avoiding unnecessary object transfer by showing
> things via ".have" lines, we're better consider references and
> reflogs that do not appear in the namespace visible from the current
> worktree.  I wanted to come up with an example of wanting to iterate
> over refs of the current worktree, but other than "what are my
> branches including HEAD?" I didn't think of anything interesting.

It doesn't show up much at the UI level, but there are some examples, like

* git log --decorate
* git for-each-ref --contains
* gitk --all

> [...]

Michael