You can create a mirror clone, but a mirror clone is a bare clone (for good reasons). That is:
[host B] git clone --mirror http://example/A.git
produces a mirror clone on B, and you can now do git clone --bare
from B
to C
:
[host C] git clone --bare <url of B.git>
The mirror clone on B will contain all references that A gave, while the bare clone on C will contain only the branch and tag references from A. That is, if repository A has references refs/heads/master
, refs/heads/develop
, refs/remotes/origin/master
, refs/replace/a23456789a23456789a23456789a23456789
, and refs/tags/v1.0
, the mirror on B has all these same references, while the bare clone on C lacks the refs/remotes/origin/master
and refs/replace/...
reference.
At any point after each clone, you can create refs/heads/
references within the clone. Hence if you want a non-bare repository on B, you can replace the middle step with:
[host B] git clone http://example/A.git
followed by a series of git update-ref
(for arbitrary reference names) or git branch
(for refs/heads/*
reference names) operations. But note that the B clone at this point has copied neither A's refs/remotes/origin/master
nor A's refs/replace/...
reference. B has:
- A's
refs/heads/master
, which B calls refs/remotes/origin/master
now
- A's
refs/heads/develop
, which B calls refs/remotes/origin/develop
now
- A's
refs/tags/v1.0
, which B calls refs/tags/v1.0
That is, B has copied A's refs/heads/*
(branch) references, but has renamed them to be remote-tracking names instead of branch names. B has copied A's tags without any name changes.
As the last step of its clone operation, B ran git checkout master
(or maybe git checkout develop
if A told it to use develop
instead). This has created B's only branch name, refs/heads/master
(or maybe refs/heads/develop
) and populated B's index and work-tree. So if you would like to make B
have, as branches, all the branches that A
had, it's relatively easy:
for all branches that were in A, but are now remote-tracking names in B:
create branch in B using the remote-tracking name we created during the clone
which you can express in whatever programming language you prefer.
There is one annoyance here, which is that the "create branch" step will fail for the one branch that was already created by the git checkout
step at the end of git clone
. To avoid the annoyance, either check for and skip that branch, or use git clone --no-checkout
to avoid creating the branch and populating the index and work-tree on B
.
Summary
- If you want a bare clone on B, using
--mirror
is an option. You will get all references.
- If you want a bare clone on B but not a mirror, use
--bare
. You will get all branch and tag references.
- If you want a non-bare clone on B, you must work harder (see above).
Repeat this for C.