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 11, 2023, 10:47 UTC
Message-ID
<87o7oz7eer.fsf@sebyte.me>
In-Reply-To
<ZAlOnTovp0ncZopf@coredump.intra.peff.net>
Hello Jeff,
Alas, I thought I understood fetch refspecs, but it appears not.

Quoth Jeff King <peff@peff.net> on Wed, 8 Mar 2023 22:12:29 -0500:

Show 26 quoted lines
> On Wed, Mar 08, 2023 at 04:54:39PM +0000, Sebastian Tennant wrote:
> […]
>> 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?
>
> Yes, that's exactly correct. In some ways it is cleaner than using
> "refs/heads/upstream" because it leaves the whole "refs/heads/"
> namespace intact for local client branches. It depends on how much
> of a pain it is to configure the extra refspec in each client. :)
I decided to go with the cleaner approach.
Here are the actions I'm taking to configure the mirror:
 $ git clone --bare https://url.of/project.git
 $ cd project.git
 $ git remote rename origin upstream
 $ git config remote.upstream.fetch\
       '+refs/heads/*:refs/remotes/upstream/*'
 $ git fetch upstream --prune

At this point there are no refs under refs/heads (and very many under refs/remotes/upstream).

Here are the actions I'm then taking on a client:
 $ git clone --bare mirror:path/to/project.git
 $ cd project.git
 $ git remote rename origin mirror
 $ git config remote.mirror.fetch\
       '+refs/heads/*:refs/remotes/mirror/*'

At this point, both mirror and client have a normal fetch refspec, i.e. no additional refspec has been added to the client, yet when I run:

 $ git fetch mirror --prune

on the client, all the refs on mirror under refs/remotes/upstream are fetched and placed under refs/remotes/mirror on the client.

My understanding of refspec:
 +refs/heads/*:refs/remotes/mirror/*

is "fetch only those refs under refs/heads and place them under refs/remotes/mirror", which in this case should mean that no refs are fetched (since there are none on mirror under refs/heads).

What's going on here that I'm just not getting?
If I add the additional refspec to the client:
 $ git config --add remote.mirror.fetch\
   '+refs/remotes/upstream/*:refs/remotes/upstream/*'

and fetch once more, I end up with all the refs already under refs/remotes/mirror duplicated under refs/remotes/upstream.

Sebastian
Previous: Jeff KingNext: Jeff King
Message 7 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.