git克隆帮助页面有这样说——mirror:

设置远程存储库的镜像。这意味着——裸露。

但没有详细说明——mirror克隆与——bare克隆的不同之处。


$ git clone --mirror $URL

速记是为了什么

$ git clone --bare $URL
$ (cd $(basename $URL) && git remote add --mirror=fetch origin $URL)

(从这里直接复制)

当前的手册是这么说的:

与——bare相比,——mirror不仅将源的本地分支映射到目标的本地分支,它还映射所有的引用(包括远程分支,notes等),并设置一个refspec配置,以便所有这些引用都被目标库中的git远程更新覆盖。


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.

新的文档基本上都是这么说的:

——镜子 设置源存储库的镜像。这意味着——裸露。与——bare相比,——mirror不仅将源的本地分支映射到目标的本地分支,它还映射所有的引用(包括远程分支,notes等),并设置一个refspec配置,以便所有这些引用都被目标库中的git远程更新覆盖。

我最初的回答还指出了裸克隆和正常(非裸)克隆之间的区别——非裸克隆设置远程跟踪分支,只为HEAD创建一个本地分支,而裸克隆直接复制分支。

假设origin有一些分支(master (HEAD), next, pu和maint),一些标签(v1, v2, v3),一些远程分支(devA/master, devB/master),和一些其他的引用(refs/foo/bar, refs/foo/baz,可能是notes, stashes,其他devs的命名空间,谁知道呢)。

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.


一个克隆复制的裁判从远程和stuff他们到一个子目录名为“这些是裁判,远程拥有”。

镜像从远程复制裁判,并把他们放在自己的顶级-它替换自己的裁判与那些远程。

这意味着当有人从你的镜像中提取并将镜像的引用放入他们的子目录时,他们将得到与原始镜像相同的引用。从最新镜像中获取的结果与直接从初始回购中获取的结果相同。


我今天对git-2.0.0的测试表明——mirror选项没有复制钩子、配置文件、描述文件、info/exclude文件,至少在我的测试用例中没有复制一些引用(我不理解)。我不会称它为“功能完全相同的副本,可以与原件互换”。

-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

GitHub文档中关于复制存储库的详细解释:

与裸克隆一样,镜像克隆包括所有远程分支和标记,但每次获取时都会覆盖所有本地引用,因此它始终与原始存储库相同。


我添加了一张图片,显示镜像和裸之间的差异。 左边是光秃秃的,右边是镜子。你可以清楚,镜像的配置文件有fetch key,这意味着你可以通过git remote update或git fetch——all来更新它


$ git clone --bare https://github.com/example

这个命令将使新的“example”目录本身为$GIT_DIR(而不是example/.git)。同样,远程的分支头被直接复制到相应的本地分支头,而不需要映射。使用此选项时,既不会创建远程跟踪分支,也不会创建相关配置变量。

$ git clone --mirror https://github.com/example

与裸克隆一样,镜像克隆包括所有远程分支和标记,但所有本地引用(包括远程跟踪分支、注释等)在每次获取时都将被覆盖,因此它将始终与原始存储库相同。


与git clone不同,git clone -mirror和git clone -bare都是裸回购。它们之间的区别在配置文件中。

Git克隆的配置文件如下所示:

[remote "origin"]
    url = https://github.com/example
    fetch = +refs/heads/*:refs/remotes/origin/*

Git克隆——bare的配置文件如下所示:

[remote "origin"]
    url = https://github.com/example

Git克隆——镜像的配置文件如下:

[remote "origin"]
    url = https://github.com/example
    fetch = +refs/*:refs/*
    mirror = true

我们看到,主要的区别在于用于取回的refspec

refspec的格式首先是一个可选的+,然后是 <src>:<dst>,其中<src>是在 远端和<dst>是跟踪这些引用的地方 本地。+告诉Git更新引用,即使它不是 快进。

对于由git remote add origin命令自动写入的git克隆,git获取服务器上refs/heads/下的所有引用,并将它们写到refs/remotes/origin/ local。

在git clone -bare的情况下,没有refspec用于抓取。

对于git clone——mirror,用于抓取的refspec看起来像fetch = +refs/*:refs/*。这意味着,标签,remotes, replace(在refs目录下)以及头部也将被获取。注意,默认情况下,git克隆只获取头部。

注1:git clone——mirror和git clone——bare——mirror是等价的。

注2:也有不同的包装参考。因为它记录的信息与refs/heads/, refs/tags/和好友记录的信息相同,以一种更有效的方式记录。