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

Re: How to mirror and augment a git repository

From
STSebastian Tennant <sdt@sebyte.me>
Date
Mar 8, 2023, 16:54 UTC
Message-ID
<87fsaf9oa8.fsf@sebyte.me>
In-Reply-To
<ZAWfkkmrPUqNmrtu@coredump.intra.peff.net>
Hello Jeff,
Thanks for your explanation.  It's been really helpful.

Quoth Jeff King <peff@peff.net> on Mon, 6 Mar 2023 03:08:50 -0500:

Show 16 quoted lines
> On Sat, Mar 04, 2023 at 12:19:16PM +0000, Sebastian Tennant wrote:
>
>>  Augmented mirror:
>>
>>    $ git clone --mirror <upstream> upstream
>>    $ cd upstream
>>    $ git remote update  # regular cron job
>
> The problem here is that your refspec for "origin" in the mirror
> will be "+refs/*:refs/*". So it claims to have responsibility for
> the whole refs namespace. And because of the "+", it will happily
> overwrite local refs when fetching, including branches pushed up by
> the client. You noticed it most with "prune", because that deletes
> local branches not present in upstream repo. But a similar problem
> would happen if both a client and the upstream had a branch named
> "foo".
Understood.
Show 10 quoted lines
>> I've tried running the augmented mirror as a plain bare repo, i.e.
>>
>>    $ git config --unset remote.origin.fetch
>>    $ git config --unset remote.origin.mirror
>>
>> but then the cron job (git remote update) is no longer sufficient in
>> making all upstream activity available downstream.
>
> Right. If you drop the fetch refspec entirely, then it will only fetch
> HEAD during your cron jobs, which is not what you want.
Precisely.
Show 7 quoted lines
> You want a refspec that tells Git to fetch everything, but you need
> to divide up the "refs/" namespace into local stuff and mirrored
> stuff.
>
> You could use the normal "+refs/heads/*:refs/remotes/origin/*" refspec,
> but it's awkward for the clients to access "refs/remotes/" on the
> mirror.

Indeed. To fetch a known ref, a client (also with the normal fetch refspec) would have to do something like this, for example:

 $ git fetch origin\
       refs/remotes/origin/<ref>:refs/remotes/upstream/<ref>

Alternatively, they could add an additional fetch refspec to their config:

[remote="origin"]
 ...
 fetch = +refs/heads/*:refs/remotes/origin/*             # normal
 fetch = +refs/remotes/origin/*:refs/remotes/upstream/*  # additional

This would have the advantage of fetching all the upstream refs on the next update giving them a better idea of what's happening upstream.

Is my understanding more or less correct?
Show 8 quoted lines
> So you probably want to keep the upstream branches in "refs/heads/",
> but mark a special part of the namespace. Like:
>
>   cd augmented-mirror
>   git config remote.origin.fetch '+refs/heads/*:refs/heads/upstream/*'
>
> And then "git fetch" will pull all of the remote branches into the
> "upstream/" namespace.

I see. And creating the 'upstream' namespace under 'heads' (instead of under 'remotes') is crucial, since any client (with a normal fetch refspec) will then receive those refs automatically, i.e. without the additional fetch refspec I've described above.

> And it's safe to prune, because it will only delete branches in
> refs/heads/upstream/ (and you may want to just "git fetch --prune"
> as you fetch via cron, which is a little more efficient than a
> separate "git remote prune").
Understood and noted.
> Clients can name their branches whatever they like, as long as they
> don't start with "upstream/", and that won't interfere with the
> mirror.
Got it.  Thanks again.
Sebastian
Previous: Jeff KingNext: Jeff King
Message 5 of 10 in “How to mirror and augment a git repository”
  1. Sebastian TennantMar 4, 2023
  2. Bagas SanjayaMar 5, 2023
  3. Sebastian TennantMar 5, 2023
  4. Jeff KingMar 6, 2023
  5. Sebastian TennantMar 8, 2023
  6. Jeff KingMar 9, 2023
  7. Sebastian TennantMar 11, 2023
  8. Jeff KingMar 11, 2023
  9. Sebastian TennantMar 12, 2023
  10. Jeff KingMar 13, 2023

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.