Thanks for that very thorough response.
The rationale for this is somewhat convoluted...I have a vendor-supplied
build system that expects to be pointed at a bare repository. For
performance reasons I want to have a local bare repo on each build
machine that can be kept in sync with a master repo on a main server.
Chris
On 09/22/2011 12:50 PM, Michael Witten wrote:
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
--
Chris Friesen
Software Developer
GENBAND
chris.friesen@xxxxxxxxxxx
www.genband.com
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html