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/masterIn 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/parentIn 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/parentIn particular:
fetch = +refs/*:refs/*
That's a very liberal refspec! It basically says that fetch should mirror everything by default.
Sincerely, Michael Witten