git clone 实际上是如何工作的

19

我在Github上有一个仓库,里面有两个分支: masterdevelop

当我克隆这个仓库并运行 $ git branch 命令时,只显示了 master 分支。
如果我运行 $ git branch -a 命令,就可以看到所有的远程分支。

现在,如果我运行 $ git checkout develop 命令,会收到以下消息:

分支 develop 设置为跟踪来自 origin 的远程分支 develop。
切换到新分支 'develop'

实际发生了什么?当我运行 $ git clone remote-url 命令时,是否已经获取了来自远程 develop 分支的提交记录,还是在运行 $ git checkout develop 命令时才获取,还是二者都没有获取?

在检出 develop 分支后,我需要运行 $ git pull origin develop 命令吗,或者已经完成了同步?

请帮助我理解当远程存在多个分支时,如何使用 clone 命令。

5个回答

22
简单来说,git clone repository-url 做的事情如下所示:
  1. 创建一个新的空仓库。

  2. git init
    
  3. 创建名为 "origin" 的远程,并将其设置为给定的url。

  4. git remote add origin repository-url
    
  5. 从名为“origin”的远程仓库获取所有提交和远程分支。

  6. git fetch --all
    
  7. 创建一个名为"master"的本地分支,以追踪远程分支"origin/master"。

  8. git checkout --track origin/master
    
  9. 有趣的一点是,GitHub或Bitbucket中的分支只是服务器端的克隆。

1
谢谢,这正是我在寻找的。 - Michael
2
这是一个很好的答案,但是为了记录 - 第一步是为仓库主目录创建mkdir - bloody

13

git clone获取所有远程分支,但只为您创建一个本地分支master。因此,当您运行git branch -a时,您将看到如下内容:

$ git branch -a
* master
  remotes/origin/HEAD
  remotes/origin/develop
  remotes/origin/master

这意味着你有一个本地分支master和几个远程分支。当你运行git checkout develop时,git会创建另一个本地分支develop跟踪远程分支origin/developgit尝试同步跟踪分支,因此您不必在check out之后再执行pull
如果本地和远程分支术语让您感到困惑,您可以浏览此文档。它有一些漂亮的图表帮助您理解它们,以及当您进行进一步提交时本地和远程分支如何移动。
您可能会发现这个答案有帮助:如何克隆Git中的所有远程分支?,第一个答案。

谢谢大家,每一个人。现在我明白了。因为它有最完整的解释,我接受了这个答案。 - Tamás Pap
谢谢,这很有用。有一个小问题,你说“git尝试同步跟踪分支,因此在检出后不必进行另一次拉取”,这似乎暗示了检出会作为过程的一部分同步远程跟踪分支。事实并非如此,只有git fetch将从远程检索更新(或者使用fetch作为过程的第一部分的git pull)。检出只使用现有的本地副本分支。远程跟踪只是将本地分支与远程链接,以简化拉取时的命令,它不添加任何同步功能。 - user2493235

10

git clone 首先创建一个新的空仓库(类似于 git init)。

然后将给定的仓库设置为名为“origin”的远程仓库。(git remote add

主要工作由 git fetch 完成,这是唯一与其他仓库通信的命令。它将远程仓库的所有提交转移到当前仓库,并在本地仓库中创建以“remote/origin/”开头的分支,对应于远程仓库上的分支。

如果你有一个默认的非裸仓库,那么它还会调用 git checkout 来检出通常是主分支。

如果你调用 git branch -r,它将显示“远程”分支,即你的仓库中那些将通过 git fetch 更新的分支。(你永远不直接在这些分支上工作)

每当你想要在一个分支上工作时,你使用 git checkout 创建该分支的副本,而没有“remote/origin/”前缀。这些是你工作的“本地”分支。(git branch 将显示这些分支)

你做的几乎所有事情都只涉及你的本地仓库。唯一的例外是 git push,这是更新远程仓库的唯一命令,以及 git fetch,这是查询其他仓库的唯一命令。

git pull 只是 git fetchgit merge 的组合。第一个命令获取更改并更新 remote/origin/*,第二个命令将这些更改合并到你的本地分支中。


1

1
当您克隆存储库时,您将获得所有分支和可以从任何这些分支访问的所有提交。
但是,您不会获得除主分支以外的任何其他分支的本地分支。其他分支作为远程分支存在(remotes / origin / development),您可以随时检出其中任何一个。git将在您进行检出时在远程分支和本地分支之间建立跟踪。

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