Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
–
The difference is that when using
--mirror
,
all
refs are copied
as-is
. This means everything: remote-tracking branches, notes, refs/originals/* (backups from filter-branch). The cloned repo has it all. It's also set up so that a remote update will re-fetch everything from the origin (overwriting the copied refs). The idea is really to mirror the repository, to have a total copy, so that you could for example host your central repo in multiple places, or back it up. Think of just straight-up copying the repo, except in a much more elegant git way.
The new
documentation
pretty much says all this:
--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 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.
My original answer also noted the differences between a bare clone and a normal (non-bare) clone - the non-bare clone sets up remote tracking branches, only creating a local branch for
HEAD
, while the bare clone copies the branches directly.
Suppose origin has a few branches (
master (HEAD)
,
next
,
pu
, and
maint
), some tags (
v1
,
v2
,
v3
), some remote branches (
devA/master
,
devB/master
), and some other refs (
refs/foo/bar
,
refs/foo/baz
, which might be notes, stashes, other devs' namespaces, who knows).
git clone origin-url
(non-bare):
You will get all of the tags copied, a local branch
master (HEAD)
tracking a remote branch
origin/master
, and remote branches
origin/next
,
origin/pu
, and
origin/maint
. The tracking branches are set up so that if you do something like
git fetch origin
, they'll be fetched as you expect. Any remote branches (in the cloned remote) and other refs are completely ignored.
git clone --bare origin-url
:
You will get all of the tags copied, local branches
master (HEAD)
,
next
,
pu
, and
maint
, no remote tracking branches. That is, all branches are copied as is, and it's set up completely independent, with no expectation of fetching again. Any remote branches (in the cloned remote) and other refs are completely ignored.
git clone --mirror origin-url
:
Every last one of those refs will be copied as-is. You'll get all the tags, local branches
master (HEAD)
,
next
,
pu
, and
maint
, remote branches
devA/master
and
devB/master
, other refs
refs/foo/bar
and
refs/foo/baz
. Everything is exactly as it was in the cloned remote. Remote tracking is set up so that if you run
git remote update
all refs will be overwritten from origin, as if you'd just deleted the mirror and recloned it. As the docs originally said, it's a mirror. It's supposed to be a functionally identical copy, interchangeable with the original.
–
–
–
–
–
–
–
–
My tests with git-2.0.0 today indicate that the --mirror option does not copy hooks, the config file, the description file, the info/exclude file, and at least in my test case a few refs (which I don't understand.) I would not call it a "functionally identical copy, interchangeable with the original."
-bash-3.2$ git --version
git version 2.0.0
-bash-3.2$ git clone --mirror /git/hooks
Cloning into bare repository 'hooks.git'...
done.
-bash-3.2$ diff --brief -r /git/hooks.git hooks.git
Files /git/hooks.git/config and hooks.git/config differ
Files /git/hooks.git/description and hooks.git/description differ
Only in hooks.git/hooks: applypatch-msg.sample
Only in /git/hooks.git/hooks: post-receive
Files /git/hooks.git/info/exclude and hooks.git/info/exclude differ
Files /git/hooks.git/packed-refs and hooks.git/packed-refs differ
Only in /git/hooks.git/refs/heads: fake_branch
Only in /git/hooks.git/refs/heads: master
Only in /git/hooks.git/refs: meta
–
–
A clone copies the refs from the remote and stuffs them into a subdirectory named 'these are the refs that the remote has'.
A mirror copies the refs from the remote and puts them into its own top level - it replaces its own refs with those of the remote.
This means that when someone pulls from your mirror and stuffs the mirror's refs into thier subdirectory, they will get the same refs as were on the original. The result of fetching from an up-to-date mirror is the same as fetching directly from the initial repo.
Unlike git clone, git clone --mirror and git clone --bare both are bare repos. The difference between them are in the config file.
git clone's config file looks like:
[remote "origin"]
url = https://github.com/example
fetch = +refs/heads/*:refs/remotes/origin/*
git clone --bare's config file looks like:
[remote "origin"]
url = https://github.com/example
git clone --mirror's config file looks like:
[remote "origin"]
url = https://github.com/example
fetch = +refs/*:refs/*
mirror = true
So, we see that the main difference in in the refspec to be used for fetching
The format of the refspec is, first, an optional +, followed by
<src>:<dst>, where <src> is the pattern for references on the
remote side and <dst> is where those references will be tracked
locally. The + tells Git to update the reference even if it isn’t a
fast-forward.
In case of git clone that is automatically written by a git remote add origin command, Git fetches all the references under refs/heads/ on the server and writes them to refs/remotes/origin/ locally.
In case of git clone --bare, there is no refspec to be used for fetching.
In case of git clone --mirror, the refspec to be used for fetching looks like fetch = +refs/*:refs/*. It means, tags, remotes, replace (which is under refs directory) along with heads will be fetched as well. Note that, by default git clone only fetch heads.
NOTE 1: git clone --mirror and git clone --bare --mirror are equivalent.
NOTE 2: there is also difference in packed-refs. As it records the same information as refs/heads/, refs/tags/, and friends record in a more efficient way.
$ git clone --bare https://github.com/example
This command will make the new "example" directory itself the $GIT_DIR (instead of example/.git). Also the branch heads at the remote are copied directly to corresponding local branch heads, without mapping. When this option is used, neither remote-tracking branches nor the related configuration variables are created.
$ git clone --mirror https://github.com/example
As with a bare clone, a mirrored clone includes all remote branches and tags, but all local references (including remote-tracking branches, notes etc.) will be overwritten each time you fetch, so it will always be the same as the original repository.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.