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

Re: any way to "re-sync" a bare repository against another bare repository?

From
Michael Witten <mfwitten@gmail.com>
Date
Sep 22, 2011, 18:41 UTC
Message-ID
<7142366f54c44cea82542adf8aea5bb9-mfwitten@gmail.com>
In-Reply-To
<4E7B6EDD.1040106@genband.com>
On Thu, 22 Sep 2011 11:22:37 -0600, Chris Friesen wrote:
> Suppose I have a parent bare repository.  I do a "git clone --bare" to 
> create a child repository, and then clone the child to create a 
> grandchild repository.

Firstly, what exactly is the scenario you are trying to achieve? Perhaps there is a better way to do what you are trying to do.

> If changes get pushed into the parent repository, is there any way to 
> cause the child to be updated?

The documentation answers your question (but badly, as with much of the documentation); from `git help clone':

  --bare
      Make a bare GIT repository. That is, instead of creating
      <directory> and placing the administrative files in
      <directory>/.git, make the <directory> itself the $GIT_DIR.
      This obviously implies the -n because there is nowhere to
      check out the working tree. Also the branch heads at the
      remote are copied directly to corresponding local branch
      heads, without mapping them to refs/remotes/origin/. When
      this option is used, neither remote-tracking branches nor
      the related configuration variables are created.
In particular:
                                  Also the branch heads at the
      remote are copied directly to corresponding local branch
      heads, without mapping them to refs/remotes/origin/. When
      this option is used, neither remote-tracking branches nor
      the related configuration variables are created.
In particular:
                                                           When
      this option is used, neither remote-tracking branches nor
      the related configuration variables are created.

Thus, you have to explicitly tell git what you fetched and which branch heads should be updated.

Consider this:
  $ git init parent
  $ git clone        parent child0
  $ git clone --bare parent child1
Now, look at the config file for the child0 repository:
  $ cat child0/.git/config 
  [core]
          repositoryformatversion = 0
          filemode = true
          bare = false
          logallrefupdates = true
  [remote "origin"]
          fetch = +refs/heads/*:refs/remotes/origin/*
          url = /path/to/parent
  [branch "master"]
          remote = origin
          merge = refs/heads/master
In particular:
          fetch = +refs/heads/*:refs/remotes/origin/*

That is the default `refspec'; when `git fetch' is not explicitly told on the command line what to fetch and which branch head[s] to update, then this refspec is used as a default.

Now, look at the config file for the child1 repository:
  $ cat child1/config
  [core]
          repositoryformatversion = 0
          filemode = true
          bare = true
  [remote "origin"]
          url = /path/to/parent

In particular, note that a bare repository doesn't include any such default information for `git fetch'. However, you could be explicit about it; from within the chidl1 repo:

  $ git fetch origin '+refs/heads/*:refs/remotes/origin/*'
> Just a "git fetch <parent>" doesn't seem to help.  If I set up parent as 
> a remote branch I can fetch it,

Firstly, it doesn't make any sense to say "set up parent as a remote branch"; what you mean is "set up `<parent>' as a remote with a default refspec that creates any associated remote-tracking branch heads".

Secondly, by setting up `<parent>' as a remote, you are creating the missing refspec in your config file:

  [remote "<parent>"]
          url = /path/to/parent
          fetch = +refs/heads/*:refs/remotes/<parent>/*
which is why you get this:
> but then it shows all the branches as "<parent>/<branch>" rather
> than updating the child.
You need a different refspec, namely:
  +refs/heads/*:refs/heads/*
So, either be explicit:
  git fetch '<parent>' '+refs/heads/*:refs/heads/*'
or update your config:
  git config 'remote.<parent>.fetch' '+refs/heads/*:refs/heads/*'

Of course, there is an easier way that does all of this [and more] for you:

> I just tried a "git clone --mirror" to create the child and it seems to 
> allow me to pick up changes in the parent via "git fetch".  Is that the 
> proper way to handle this?

The documentation answers your question (but badly, as with much of the documentation); from `git help clone':

  --mirror
      Set up a mirror of the source repository. This implies
      --bare. Compared to --bare, --mirror not only maps local
      branches of the source to local branches of the target, it
      maps all refs (including remote-tracking branches, notes
      etc.) and sets up a refspec configuration such that all
      these refs are overwritten by a git remote update in the
      target repository.
In particular:
                sets up a refspec configuration such that all
      these refs are overwritten by a git remote update in the
      target repository.
Consider this:
  $ git clone --mirror parent child2
  $ cat child2/config
  [core]
          repositoryformatversion = 0
          filemode = true
          bare = true
  [remote "origin"]
          fetch = +refs/*:refs/*
          mirror = true
          url = /path/to/parent
In particular:
          fetch = +refs/*:refs/*

That's a very liberal refspec! It basically says that fetch should mirror everything by default.

Sincerely, Michael Witten

Previous: Chris FriesenNext: Chris Friesen
Message 2 of 3 in “any way to "re-sync" a bare repository against another bare repository?”
  1. Chris FriesenSep 22, 2011
  2. Michael WittenSep 22, 2011
  3. Chris FriesenSep 22, 2011

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.