Git克隆一个已经被克隆的仓库

14

如果对已经克隆另一个远程仓库的存储库进行 git clone,是否会产生任何不良副作用?

3个回答

14

没有副作用,但你需要了解在克隆存储库时会发生什么。

一些理论

问题在于,当你“正常方式”克隆存储库--也就是在调用git clone时没有任何调整参数--你并不会得到与源存储库相同的存储库。它确实包含完全相同的历史记录,但是却有不同的分支布局。

为了以非科学的方式解释这个问题,让我们来看一个例子:

  1. 源存储库包含“master”、“dev”和“release”三个分支。

    它还包含两个标签,“v1”和“v2”。

    该存储库中的“HEAD”引用指向“master”分支。

  2. 当你克隆这个存储库时,你的本地克隆将包含:

    • 三个远程跟踪分支:“origin/master”,“origin/dev”和“origin/release”。

    • 两个标签,“v1”和“v2”。

    • 一个名为“master”的本地分支,它指向与远程跟踪分支“origin/master”相同的提交。

  3. 如果你现在克隆这个克隆结果将会有:

    • 一个单一的远程跟踪分支“origin/master”。

    • 一个单一的本地分支“master”。

    • 两个标签,“v1”和“v2”。

这可能看起来很奇怪,但事实上,在手册页面中明确说明了这一点:

将存储库克隆到新创建的目录中,为克隆存储库中的每个分支创建远程跟踪分支(可使用git branch -r查看),并创建并检出一个初始分支,该分支是从克隆存储库当前活动分支分叉出来的。

克隆后,仅使用 "git fetch" 命令将更新所有远程跟踪分支,并且 "git pull" 命令还将合并远程主分支到当前主分支中(如果有的话),除非使用了 "--single-branch" 选项(请参见下文)。
创建对远程分支头引用以在 "refs/remotes/origin" 下找到它们,并初始化 "remote.origin.url" 和 "remote.origin.fetch" 配置变量来实现此默认配置。
因为 Git 是分布式版本控制系统,所以非裸库中的所有分支都归属于您,您可以在这些分支上工作,并决定何时以及为何将它们与其他存储库中的分支同步。
当您以 "普通方式" 克隆一个存储库时,Git 只会获取该存储库的本地分支,不会考虑任何远程跟踪分支。这是因为远程跟踪分支作为其他存储库状态的标记,不包含任何工作内容。
使用 "--mirror" 命令行选项克隆存储库可以得到真正的副本,但结果将是裸库。如果再次使用 "--mirror" 命令行选项重新克隆生成的库,则会再次获得真正的副本。如果您执行了“普通”克隆操作(我猜您确实这样做了),则仍然可以从该存储库中获取所有内容,但是`git clone`将不起作用:您需要执行`git init`,然后执行`git remote add origin `,最后进行一个特别设计的`git fetch`。
如何准确地设计`git fetch`取决于您真正想从源存储库中抓取什么以及放置到哪里。首先,请注意,源存储库现在有"origin/master"和"master"两个分支,它们可能包含不同的历史记录。
还请注意,使用`git clone --mirror`克隆非裸库是可行的,但结果可能不太合理,因为在这种情况下,`git clone`会忠实地复制来自源仓库的所有分支-本地和远程跟踪分支,并且远程跟踪分支通常不应该存在于裸库中。

@dr_rk,如适用,将“远程分支”更改为“远程跟踪分支”-对于混淆表示抱歉。在这个领域的术语中,“远程”一词使用过于频繁,因此我决定坚持官方手册,即使我希望您理解“远程分支”的真正含义。 - kostix

2

如果一开始没有检出初始存储库的分支,那么您肯定会错过它们。


0

没有副作用。您可以安全地克隆通过git clone操作得到的存储库。顺便说一下,这就是git与像Subversion这样的集中式系统不同之处:克隆的存储库是原始存储库的完全副本(除了需要手动检出的分支)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接