git clone命令的帮助页面对于--mirror
选项的解释如下:
设置远程仓库的镜像。这意味着使用
--bare
选项。
但是该介绍没有详细说明--mirror
克隆与--bare
克隆有何不同。
--mirror
时,所有引用都会按原样复制。这意味着包括远程跟踪分支、注释、refs/originals/*(来自filter-branch的备份)等所有内容都会被复制到克隆仓库中。它也被设置为远程更新将从源重新获取所有内容(覆盖已复制的引用)。其实这个想法就是要镜像存储库,以便完全复制,例如可以在多个地方托管中央存储库或对其进行备份。可以将其视为直接复制存储库,只不过是以更加优雅的Git方式。我的原始答案还指出了裸克隆和普通(非裸)克隆之间的区别-非裸克隆设置远程跟踪分支,仅为
--mirror
设置源存储库的镜像。这意味着
--bare
。与--bare
相比,--mirror
不仅将源的本地分支映射到目标的本地分支,还将所有引用(包括远程分支、注释等)映射并设置refspec配置,以使所有这些引用都被目标存储库中的git remote update
覆盖。
HEAD
创建本地分支,而裸克隆直接复制分支。master(HEAD)
、next
、pu
和maint
)、一些标签(v1
、v2
、v3
)、一些远程分支(devA/master
、devB/master
)和一些其他引用(refs/foo/bar
、refs/foo/baz
,可能是注释、存储、其他开发人员的命名空间等)。
git clone origin-url
(非裸仓库):你会得到所有的标签,一个本地分支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
,所有引用将从origin覆盖,就像你刚刚删除了镜像并重新克隆它一样。正如文档最初所说的那样,这是一个镜像。它应该是一个功能上完全相同的副本,可以与原始版本交换。
$ git clone --mirror $URL
是一个简写形式
$ git clone --bare $URL
$ (cd $(basename $URL) && git remote add --mirror=fetch origin $URL)
以下翻译内容直接从这里复制而来:
当前手册是这样描述的:
--mirror
不仅会映射源仓库的本地分支到目标仓库的本地分支,还会映射所有引用(包括远程分支、注释等),并设置一个 refspec 配置,以便在目标仓库中通过git remote update
命令覆盖所有这些引用。
git fetch
,才能使它与实际内容完全相同。无论如何,这有点不是正面回答问题——问题的重点在于“镜像远程/克隆与普通的有什么不同?” - Cascabelbasename
是一个通常用于Unix的实用工具,它可以剥离路径中的目录部分,而 $()
则是Bash命令替换的简写。 - Victor Zamanian--mirror
。只有在解释了git remote add --mirror
的作用后,这才是一个可以接受的答案。 - Zenexer我今天用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
与裸克隆一样,镜像克隆包括所有远程分支和标签,但每次获取时都会覆盖所有本地引用,因此它始终与原始存储库相同。
--prune
选项来删除本地不再存在于远程的引用。 - nishanthshanmugham克隆会将远程的引用复制并放入名为“这些是远程拥有的引用”的子目录中。
镜像会将远程引用复制并放入自己的顶层目录中,它会用远程的引用替换自己的引用。
这意味着,当有人从你的镜像拉取并将镜像的引用放入他们的子目录时,他们会得到与原始引用相同的引用。从最新的镜像获取的结果与直接从初始仓库获取的结果相同。
[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
+
,后面跟着<src>:<dst>
,其中<src>
是远程端参考的模式,而<dst>
是本地跟踪这些参考的位置。如果+
前缀出现在引用规范中,则表示不管是否快进,Git 都会更新该引用。git remote add origin
命令编写的git clone
情况下,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
。git clone --mirror
和git clone --bare --mirror
是等价的。packed-refs
方面的差异。由于它以更有效的方式记录与refs/heads
,refs/tags/
和相关信息相同。$ git clone --bare https://github.com/example
example
”目录本身成为$GIT_DIR(而不是example/.git
)。此外,远程分支头将直接复制到相应的本地分支头,而无需映射。当使用此选项时,既不会创建remote-tracking分支,也不会创建相关的配置变量。$ git clone --mirror https://github.com/example