
[英]What is the difference between git clone --mirror and a simple copy of a bare repo
[英]What's the difference between git clone --mirror and git clone --bare
git clone 帮助页面对--mirror
有这样的说法:
设置远程存储库的镜像。 这意味着
--bare
。
但没有详细说明--mirror
克隆与--bare
克隆有何不同。
不同之处在于,使用--mirror
时,所有refs 都按原样复制。 这意味着一切:远程跟踪分支、注释、refs/originals/*(来自过滤器分支的备份)。 克隆的 repo 拥有一切。 它还设置为远程更新将从源重新获取所有内容(覆盖复制的参考)。 这个想法实际上是镜像存储库,拥有一个完整的副本,这样您就可以在多个地方托管您的中央存储库,或者备份它。 想想直接复制 repo,除了更优雅的 git 方式。
新文档几乎说明了所有这些:
--mirror
设置源存储库的镜像。 这意味着
--bare
。 与--bare
相比,--mirror
不仅将源的本地分支映射到目标的本地分支,它还映射所有 refs(包括远程分支、注释等)并设置 refspec 配置以覆盖所有这些 refs通过目标存储库中的git remote update
。
我最初的回答还指出了裸克隆和普通(非裸)克隆之间的区别——非裸克隆设置远程跟踪分支,只为HEAD
创建本地分支,而裸克隆直接复制分支。
假设 origin 有几个分支( master (HEAD)
、 next
、 pu
和maint
)、一些标签( v1
、 v2
、 v3
)、一些远程分支( devA/master
、 devB/master
)和一些其他参考( 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
、 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
。
我今天对 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
仅获取heads
。
注 1: git clone --mirror
和git clone --bare --mirror
是等价的。
注意 2: packed-refs
也有区别。 因为它记录的信息与refs/heads/
、 refs/tags/
和朋友记录的信息相同,以更有效的方式记录。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.