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

Re: [PATCH 2/2] worktree.c: use submodule interface to access refs from another worktree

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Feb 9, 2017, 08:04 UTC
Message-ID
<3ac5517a-aa82-7078-91a5-e182e1faed1a@alum.mit.edu>
In-Reply-To
<xmqqpoirsvin.fsf@gitster.mtv.corp.google.com>
On 02/09/2017 07:55 AM, Junio C Hamano wrote:
Show 42 quoted lines
> Michael Haggerty <mhagger@alum.mit.edu> writes:
> 
>> There are two meanings of the concept of a "ref store", and I think this
>> change muddles them:
>>
>> 1. The references that happen to be *physically* stored in a particular
>>    location, for example the `refs/bisect/*` references in a worktree.
>>
>> 2. The references that *logically* should be considered part of a
>>    particular repository. This might require stitching together
>>    references from multiple sources, for example `HEAD` and
>>    `refs/bisect` from a worktree's own directory with other
>>    references from the main repository.
>>
>> Either of these concepts can be implemented via the `ref_store` abstraction.
>> ...
>> The `ref_store` that you want here for a worktree is not the worktree's
>> *logical* `ref_store`. You want the worktree's *physical* `ref_store`.
>> Mixing logical and physical reference stores together is a bad idea
>> (even if we were willing to ignore the fact that worktrees are not
>> submodules in the accepted sense of the word).
> 
> I am not quite sure what mental model you are suggesting as a
> preferred solution.  We can
> 
>  - represent a set of refs stored for a particular worktree
>    (i.e. HEAD, refs/bisect, and refs/worktree/<name>, iirc), as
>    bunch of ref_stores;
> 
>  - represent a set of refs shared across a set of worktrees that
>    share the primary one, as another ref_store;
> 
>  - a caller who wants to get a "logical" view of a single worktree
>    user can pick one of the first kind and union that with the
>    second one, and represent the result as a (synthetic) ref_store.
> 
> The third one is "stitching together from multiple sources".  By
> "mixing logical and physical is a bad idea", do you mean that the
> same abstraction "ref_store" should not be used for the first two
> (which are physical) and the third one (which is logical)?  Do you
> want to call the first two "physical_ref_store"and the last one
> "ref_store" and keep them distinct?

The existing `ref_store` abstraction, I think, is capable of representing either kind of reference store. The stitching together to get the "logical" view of a worktree should probably happen within the refs code rather than forcing callers to deal with it. But yes, I think that code should put together a compound `ref_store` object that delegates to multiple underlying `ref_store` objects as you've described.

Which kind of `ref_store *` you have in your hand would depend on where you got it. If you call the hypothetical `get_submodule_refs()` function, you would get a `ref_store *` representing the references that are logically visible from that submodule. There might be a separate `get_worktree_specific_refs()` that returns a `ref_store *` representing the worktree-specific references physically stored for the worktree. But maybe the latter is not even necessary; see below.

Show 26 quoted lines
> For the purpose of anchoring objects in the object store shared by
> multiple worktrees, we can either iterate over all the ref_stores
> of the first two kind, or iterate over all the ref_stores of the
> third kind for all worktrees.  The latter of course is less
> efficient as the enumeration
> 
> 	for worktree in all worktrees:
> 		for ref in get_ref_store(worktree)
> 			mark tip of ref reachable
> 
> will work on all the shared refs multiple times, but as an
> abstraction that may be simpler.  The alternative of working at the
> physical level would be more efficient
> 
> 	for worktree in all worktrees:
> 		for ref in get_ref_store_specific_to_worktree(worktree):
> 	        	mark tip of ref reachable
> 	for ref in get_ref_store_shared_across_worktrees():
>         	mark tip of ref reachable
> 
> but this consumer now _knows_ how the logical ref_store of a
> worktree is constructed (i.e. by combining the two ref_stores),
> which appears as a layering violation.
> 
> I am however not sure if these issues are what you are driving at,
> and what exact design you are suggesting.

Reachability is a special case, because it needs all of the references that refer to a particular object store, even though the reference names might overlap. I personally think that reachability roots should be requested via a new refs API call separate from `for_each_rawref()` (or whatever is used now). Internally it would be implemented much like your second "efficient" algorithm, but the implementation would be within the refs code, and the caller could remain ignorant of those details.

Externally, it might not even want to pass the caller the real reference names (I assume that callers mainly only use the reference names for diagnostic messages). For example, it might want to report references `HEAD` and `refs/bisect/bad` in worktree `foo` under the pseudonyms `worktree/foo/HEAD` and `worktree/foo/refs/bisect/bad`, so that they can be distinguished from any homonyms in the main repo and in other worktrees. If you ask for the reachability roots while in a worktree, it would either automatically crawl up to the main repository and across to sibling worktrees to get the full set of reachability roots, or maybe it would refuse to run at all (if we want to require such commands to be executed from the main repo).

I don't know exactly who would be the consumers of the reachability roots, so maybe there are some problems with this suggestion.

Michael
Previous: Junio C HamanoNext: Duy Nguyen
Message 10 of 51 in “Kill manual ref parsing code in worktree.c”
  1. 0/2 Kill manual ref parsing code in worktree.cNguyễn Thái Ngọc Duy, Feb 8, 2017
  2. 1/2 refs.c: add resolve_ref_submodule()Nguyễn Thái Ngọc Duy, Feb 8, 2017
  3. Michael HaggertyFeb 9, 2017
  4. 2/2 worktree.c: use submodule interface to access refs from another worktreeNguyễn Thái Ngọc Duy, Feb 8, 2017
  5. Stefan BellerFeb 8, 2017
  6. Junio C HamanoFeb 8, 2017
  7. Junio C HamanoFeb 8, 2017
  8. Michael HaggertyFeb 9, 2017
  9. Junio C HamanoFeb 9, 2017
  10. Michael HaggertyFeb 9, 2017
  11. Duy NguyenFeb 9, 2017
  12. Michael HaggertyFeb 9, 2017
  13. Junio C HamanoFeb 8, 2017
  14. 0/5 Kill manual ref parsing code in worktree.cNguyễn Thái Ngọc Duy, Feb 16, 2017
  15. 1/5 refs: introduce get_worktree_ref_store()Nguyễn Thái Ngọc Duy, Feb 16, 2017
  16. 2/5 refs.c: add refs_resolve_ref_unsafe()Nguyễn Thái Ngọc Duy, Feb 16, 2017
  17. 3/5 worktree.c: kill parse_ref() in favor of refs_resolve_ref_unsafe()Nguyễn Thái Ngọc Duy, Feb 16, 2017
  18. 4/5 refs: add refs_create_symref()Nguyễn Thái Ngọc Duy, Feb 16, 2017
  19. 5/5 refs: kill set_worktree_head_symref()Nguyễn Thái Ngọc Duy, Feb 16, 2017
  20. 0/4 Kill manual ref parsing code in worktree.cNguyễn Thái Ngọc Duy, Mar 18, 2017
  21. 4/4 refs: kill set_worktree_head_symref()Nguyễn Thái Ngọc Duy, Mar 18, 2017
  22. 3/4 worktree.c: kill parse_ref() in favor of refs_resolve_ref_unsafe()Nguyễn Thái Ngọc Duy, Mar 18, 2017
  23. 2/4 refs: introduce get_worktree_ref_store()Nguyễn Thái Ngọc Duy, Mar 18, 2017
  24. Michael HaggertyMar 20, 2017
  25. Duy NguyenMar 20, 2017
  26. Michael HaggertyMar 20, 2017
  27. Duy NguyenMar 26, 2017
  28. 1/4 environment.c: fix potential segfault by get_git_common_dir()Nguyễn Thái Ngọc Duy, Mar 18, 2017
  29. Junio C HamanoMar 18, 2017
  30. Duy NguyenMar 19, 2017
  31. Junio C HamanoMar 18, 2017
  32. 0/5 Kill manual ref parsing code in worktree.cNguyễn Thái Ngọc Duy, Apr 4, 2017
  33. 1/5 environment.c: fix potential segfault by get_git_common_dir()Nguyễn Thái Ngọc Duy, Apr 4, 2017
  34. 2/5 refs.c: make submodule ref store hashmap genericNguyễn Thái Ngọc Duy, Apr 4, 2017
  35. 3/5 refs: introduce get_worktree_ref_store()Nguyễn Thái Ngọc Duy, Apr 4, 2017
  36. Michael HaggertyApr 22, 2017
  37. 4/5 worktree.c: kill parse_ref() in favor of refs_resolve_ref_unsafe()Nguyễn Thái Ngọc Duy, Apr 4, 2017
  38. 5/5 refs: kill set_worktree_head_symref()Nguyễn Thái Ngọc Duy, Apr 4, 2017
  39. Junio C HamanoApr 14, 2017
  40. Junio C HamanoApr 14, 2017
  41. Duy NguyenApr 14, 2017
  42. Junio C HamanoApr 17, 2017
  43. Michael HaggertyApr 22, 2017
  44. 0/6 Kill manual ref parsing code in worktree.cNguyễn Thái Ngọc Duy, Apr 24, 2017
  45. 1/6 environment.c: fix potential segfault by get_git_common_dir()Nguyễn Thái Ngọc Duy, Apr 24, 2017
  46. 2/6 refs.c: make submodule ref store hashmap genericNguyễn Thái Ngọc Duy, Apr 24, 2017
  47. 4/6 refs: introduce get_worktree_ref_store()Nguyễn Thái Ngọc Duy, Apr 24, 2017
  48. 5/6 worktree.c: kill parse_ref() in favor of refs_resolve_ref_unsafe()Nguyễn Thái Ngọc Duy, Apr 24, 2017
  49. 3/6 refs: add REFS_STORE_ALL_CAPSNguyễn Thái Ngọc Duy, Apr 24, 2017
  50. 6/6 refs: kill set_worktree_head_symref()Nguyễn Thái Ngọc Duy, Apr 24, 2017
  51. Junio C HamanoApr 25, 2017

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.