Git 克隆已经是克隆的存储库

Git cloning a repository that is already a clone

对已经是另一个远程存储库的克隆的存储库进行 git clone 操作是否有不良副作用?

没有副作用。您可以安全地克隆作为 git clone 操作结果的存储库。顺便说一下,这就是 git 与 Subversion 等集中式系统的不同之处:克隆的存储库是原始存储库的精确副本(除了需要手动检查的分支)。

如果最初没有签出,您肯定会错过初始存储库的分支。

没有副作用,但您应该准确了解克隆存储库时会发生什么。

一些理论

"problem" 是当你克隆一个存储库时 "the normal way"——也就是说,在调用 git clone 时没有任何时髦的旋钮调整——你 最终得到一个与源 相同 的存储库。它确实包含完全相同的历史,但它有不同的分支布局。

不科学的解释,举个例子:

  1. 源代码库包含分支 "master"、"dev" 和 "release".

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

    该存储库中的 "HEAD" 引用指向一个分支 "master"。

  2. 当您克隆此存储库时,您的本地克隆将具有:

    • 三个远程跟踪分支:"origin/master"、"origin/dev" 和 "origin/release".

    • 两个标签,"v1"和"v2"。

    • 一个名为 "master" 的 local 分支指向同一个提交 远程跟踪分支 "origin/master" 会。

  3. 如果您现在克隆此克隆,结果将是:

    • 单个远程跟踪分支 "origin/master"。

    • 一个本地分支 "master".

    • 两个标签,"v1"和"v2"。

这可能看起来很奇怪,但实际上这在 手册页:

Clones a repository into a newly created directory, creates remote-tracking branches for each branch in the cloned repository (visible using git branch -r), and creates and checks out an initial branch that is forked from the cloned repository’s currently active branch.

After the clone, a plain git fetch without arguments will update all the remote-tracking branches, and a git pull without arguments will in addition merge the remote master branch into the current master branch, if any (this is untrue when "--single-branch" is given; see below).

This default configuration is achieved by creating references to the remote branch heads under refs/remotes/origin and by initializing remote.origin.url and remote.origin.fetch configuration variables.

所以git clone中的"clone"意味着所有历史都被克隆了(除非另有说明)但是分支的布局不同。

推理是这样的:正是因为 Git是分布式VCS, 从某种意义上说,非裸存储库中的所有分支都是 "yours" 你在他们身上工作,只有你决定他们如何同步 其他存储库中的分支,时间和原因。

所以当你克隆一个 repo 时 "the normal way" Git:

  • 只获取分支 local 到那个 repo:没有远程跟踪分支 被认为是。

    这是因为远程跟踪分支作为状态的书签 其他存储库,并且没有对它们进行任何工作。

    要理解为什么 Git 会这样,请考虑在克隆时 Joe 的存储库 大多数时候你需要 Joe 的工作,而不是东西 他从他与之通信的任何随机存储库中获取。

  • 将所有获取的分支转换为生成的 repo 中的远程跟踪分支。

  • 创建一个本地分支并检查它。

    这只是一种便利,只会增加可能的混乱。

做什么

嗯,git clone 接受“--mirror”命令行选项 生成原始仓库的真实副本,但生成的仓库将 裸露。 您是否应该使用“--mirror”重新克隆生成的 repo 命令行选项,您将再次获得真实副本。

如果你做了一个 "normal" 克隆(我想你做了)你仍然可以 从该存储库中获取所有内容,但 git clone 不会删除它: 你需要做 git init 然后 git remote add origin <url> 接着是特制的 git fetch.

具体如何制作 git fetch,取决于您真正想要什么 从源代码库中获取,以及将它放在哪里。 首先,考虑源回购现在有 "origin/master" 和 "master",它们很可能包含不同的历史。

另请注意,使用 git clone --mirror 克隆非裸存储库是可行的,但结果不会很明智,因为在这种情况下 git clone 将尽职尽责地复制所有分支——本地和远程-tracking—来自源代码库 verbatim, 和 remote-tracking 分支不是您通常期望出现在裸库中的东西。