我想了解以下情况:
我和其他人正在使用Github的一个项目。我相信它除了主人之外还有几个分支(特别是“开发”)
所以我用git clone <url>
将项目克隆到我的计算机上,然后我得到了这个项目。我被告知我应该使用开发分支而不是主分支
所以我输入git branch
,看看那里有什么分支,我得到了
$ git branch
* master
什么?开发分支在哪里?
不过我做git checkout develop
,看哪!我现在在开发分支!我再次做git branch
,我可以看到
$ git checkout develop
Branch develop set up to track remote branch develop from origin.
Switched to a new branch 'develop'
$ git branch
* develop
master
这里发生了什么黑暗魔法?它说开发是为了跟踪原产地的发展!那之前发展是隐藏的吗?无法访问?
在做git log --oneline --decorate
后,我可以看到原点/开发分支,但刚刚发生了什么?
git clone
事实上,就在git clone
完成之前,你没有分支。
Git使用分支名称来记住特定的提交。每个名称都会记住一个,只有一个提交。每个提交都由其哈希ID唯一标识:像b7bd9486b055c3f967a870311e704e3bb0654e4f
这样的大丑陋数字。
这是提交自己记住以前的提交(通过他们的丑陋的哈希ID)。 Git将此调用称为每次提交的父提交。这意味着需要像master
这样的名称才能记住任何给定分支的最后一次提交。 Git将此最终提交称为分支的提示。
这也意味着我们可以使用一个不同的,不是非常分支的名称来记住其他一些Git的分支!
制作克隆涉及内部运行git fetch
。这是git fetch
从其他Git复制提交,git fetch
也复制他们的名字。他们的名字实际上是分支名称:这些记住他们的分支提示,如master
和develop
。但他们不是你的分支提示 - 还没有!你的Git将这些重命名为origin/master
和origin/develop
。你的Git的远程跟踪名称,带有origin
前缀,记住他们的名字和提示。
运行git fetch
会更新远程跟踪名称,以便您知道他们的新分支提示是什么。当然,它也首先获得他们拥有的任何提交,而不是。
[
develop
突然出现:]这里发生了什么黑暗魔法?
运行git checkout name
时,Git首先搜索name
的分支名称列表。如果它存在,Git会尝试检查作为分支name
的提示的特定提交,并将其作为当前分支。到目前为止这么好 - 但如果这个名字还不存在呢?
在这种情况下,git checkout
不仅仅是失败,而是搜索你的远程跟踪名称,如origin/master
和origin/develop
。如果只有一个类似于你要求的名称,你的Git现在会创建你自己的分支名称,将其设置为在你的分支提示提交时记住,你的Git记住的相同哈希ID作为他们的提示,使用远程跟踪名称。
所以现在你有一个develop
,现在Git可以检查出来!
事实上,这是git clone
的最后一步:这就是你如何获得master
的第一步。从origin
复制提交,并将其名称更改为origin/*
后,您的Git运行git checkout master
。你的master
还不存在,所以你的Git是用你的gaz从他们的origin/master
创建的你的master
创建的。 (哇!这似乎是漫长的过程,而且它确实很有意义!)
简短的回答
当你clone
(后来当你fetch
)时,你的本地版本的repo获得了远程分支的更新定义,但是不会自动创建本地副本。如果您只是签出一个(但不存在的本地)分支,其名称与其中一个远程分支匹配,git假定您需要跟踪它的远程版本。
试试git branch -a
看看一切。
有关更多信息,请参阅torek的完整答案,以解开其背后的细节。