git clone 帮助页面有这样的说法--mirror
:
设置远程存储库的镜像。这意味着
--bare
。
但没有详细说明--mirror
克隆与克隆有何不同--bare
。
不同之处在于,在使用 时--mirror
,所有refs 都按原样复制。这意味着一切:远程跟踪分支、注释、refs/originals/*(来自过滤器分支的备份)。克隆的 repo 拥有一切。它还设置为远程更新将从源重新获取所有内容(覆盖复制的参考)。这个想法实际上是镜像存储库,拥有一个完整的副本,这样您就可以在多个地方托管您的中央存储库,或者备份它。想想直接复制 repo,除了更优雅的 git 方式。
新文档几乎说明了所有这些:
--mirror
设置源存储库的镜像。这意味着
--bare
。与 相比--bare
,--mirror
不仅将源的本地分支映射到目标的本地分支,它还映射所有 refs(包括远程分支、注释等)并设置 refspec 配置,使得所有这些 refs 都被git remote update
目标存储库中的 a 覆盖.
我最初的回答还指出了裸克隆和普通(非裸)克隆之间的区别——非裸克隆设置远程跟踪分支,只为 创建本地分支HEAD
,而裸克隆直接复制分支。
假设 origin 有一些分支(master (HEAD)
, next
, pu
, 和maint
),一些标签(v1
, v2
, v3
),一些远程分支(devA/master
, devB/master
),以及一些其他的 refs (refs/foo/bar
, refs/foo/baz
,可能是笔记,存储,其他开发人员的命名空间,谁知道)。
git clone origin-url
(non-bare):您将复制所有标签,一个本地分支master (HEAD)
跟踪一个远程分支origin/master
,以及远程分支origin/next
、、origin/pu
和origin/maint
。跟踪分支的设置是这样的,如果您执行类似的操作git fetch origin
,它们将按照您的预期获取。任何远程分支(在克隆的远程中)和其他引用都将被完全忽略。
git clone --bare origin-url
:您将复制所有标签,本地分支、、、master (HEAD)
和,next
没有远程跟踪分支。也就是说,所有分支都按原样复制,并且完全独立设置,不期望再次获取。任何远程分支(在克隆的远程中)和其他引用都将被完全忽略。pu
maint
git clone --mirror origin-url
:这些参考中的每一个都将按原样复制。您将获得所有标签、本地分支master (HEAD)
、、、和next
、远程分支和、其他引用和。一切都与克隆遥控器中的完全一样。设置了远程跟踪,因此如果您运行所有 refs 将从原点覆盖,就好像您刚刚删除了镜像并重新克隆了它一样。正如文档最初所说,它是一面镜子。它应该是功能相同的副本,可与原件互换。pu
maint
devA/master
devB/master
refs/foo/bar
refs/foo/baz
git remote update
$ git clone --mirror $URL
是的简写
$ git clone --bare $URL
$ (cd $(basename $URL) && git remote add --mirror=fetch origin $URL)
(直接从这里复制)
当前的手册页是如何描述的:
与 相比
--bare
,--mirror
不仅将源的本地分支映射到目标的本地分支,它还映射所有 refs(包括远程分支、注释等)并设置 refspec 配置,使得所有这些 refs 都被git remote update
目标存储库中的 a 覆盖.
我今天对 git-2.0.0 的测试表明 --mirror 选项不会复制钩子、配置文件、描述文件、信息/排除文件,并且至少在我的测试用例中没有复制一些参考(我没有不明白。)我不会称它为“功能相同的副本,可与原件互换”。
-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
克隆从远程复制参考并将它们填充到名为“这些是远程具有的参考”的子目录中。
镜像从远程复制参考并将它们放入自己的顶层 - 它用远程的参考替换自己的参考。
这意味着当有人从您的镜像中拉取镜像并将镜像的 refs 填充到他们的子目录中时,他们将获得与原始镜像相同的 refs。从最新镜像中获取的结果与直接从初始存储库中获取相同。
GitHub 文档中关于复制存储库的详细解释:
与裸克隆一样,镜像克隆包括所有远程分支和标签,但每次获取时都会覆盖所有本地引用,因此它始终与原始存储库相同。
$ 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
两者都是裸回购。它们之间的区别在config
文件中。
git clone
的配置文件如下所示:
[remote "origin"]
url = https://github.com/example
fetch = +refs/heads/*:refs/remotes/origin/*
git clone --bare
的配置文件如下所示:
[remote "origin"]
url = https://github.com/example
git clone --mirror
的配置文件如下所示:
[remote "origin"]
url = https://github.com/example
fetch = +refs/*:refs/*
mirror = true
因此,我们看到用于获取的refspec中的主要区别
refspec 的格式首先是一个可选的
+
,然后是<src>:<dst>
,其中<src>
是远程端引用的模式,并且<dst>
是这些引用将在本地跟踪的位置。告诉 Git 更新引用,+
即使它不是快进的。
如果git clone
它是由git remote add origin
命令自动写入的,Git 会获取refs/heads/
服务器上的所有引用并将它们写入refs/remotes/origin/
本地。
在 的情况下git clone --bare
,没有用于获取的 refspec。
在 的情况下git clone --mirror
,用于获取的 refspec 看起来像fetch = +refs/*:refs/*
。这意味着,tags
, remotes
, replace
(在refs
目录下)也heads
将被获取。请注意,默认情况下git clone
仅 fetchheads
。
注 1: git clone --mirror
和git clone --bare --mirror
是等价的。
注2:也有区别packed-refs
。因为它记录了与 , 相同的信息refs/heads/
,refs/tags/
并且以更有效的方式记录了朋友。