我正在学习为 Github 上的开源项目做出贡献。我想尝试解决一个适用于 3.x 分支的问题,但我很困惑为什么 Github Desktop 会显示来自源站和上游的分支:
如果我正在使用 fork,我怎么可能切换到上游 repo 上的分支?这对我来说没有意义(但请记住,我来自 Mercurial 背景,所以也许我没有完全理解 Git 的分支——我认为它们以某种方式存在于版本控制之外?)。
如果上游 repo 在我的 3.x 分支上的 fork 之前有一些提交并且我单击upstream/3.x
,我的工作目录是否以某种方式从这些上游提交中获得了更改?我不认为这是有道理的,但我不明白为什么它会提供切换到上游分支。
Git 分支的工作方式类似于 Mercurial 的书签。它们并非一成不变地附加到提交,而是充当指向某个提交 ID 的灵活指针(请参阅 Mercurial 的书签文档),因此多个存储库完全有可能拥有自己的书签指向同一个提交。
(事实上,当你推送到 GitHub 时会发生这种情况——首先上传提交,然后远程存储库的“主”或“主”书签(即分支)被更新为指向它们,所以现在本地和远程书签独立指向同一个提交。类似地,当您从“master”创建一个新的本地分支时,它只是创建了第二个指向与“master”相同的提交的书签。
尽管看起来 Git 分支并没有像 Hg 书签那样严格地与远程存储库保持同步。预计会出现分歧,因此从远程存储库下载的分支始终以“reponame/”命名,而 Hg 的文档暗示应该快速处理分歧的“foo@reponame”书签。)
您不仅在处理叉子;你正在处理一个叉子的叉子。您在桌面上拥有的克隆存储库与您在 GitHub 上拥有的 fork 完全分开——它有自己的分支和一切。(“origin/”分支和“upstream/”分支实际上都不是 GH Desktop 显示的存储库的本地;它们只是远程分支的本地缓存副本。)
Git 存储库不限于有一个用于推送/拉取的 URL——在使用 fork 时通常有两个 URL,并且可以直接从两者中获取提交和分支。例如,您可以通过将“upstream/3.x”合并到本地“3.x”来集成最新的上游更改,然后推送到您的 GitHub fork 的“origin/3.x”。
是的,它确实。您的桌面存储库具有来自上游存储库的所有分支的完整副本(截至上次提取),您可以检查它们的提交,从它们创建本地分支,将单个提交合并或挑选到本地分支等。(这比“上游”更通用,您可以配置任意数量的遥控器,例如跟踪其他人的开发分支。)
然而,至少使用命令行
git
工具,检出远程分支(无论是“origin/3.x”还是“upstream/3.x”)是一个临时操作——它不会自动创建一个本地分支你可以继续工作,它只检查一个“分离的”提交。你仍然可以创建一个分支,它不是自动的。(尽管如果你尝试检查一个不存在的本地“3.x”分支,Git 会神奇地从“origin/3.x”创建它。)
我已经很长时间没有使用 GitHub Desktop,所以我不知道如果您通过 GUI 检查远程分支会发生什么——它可能会创建一个以远程命名的本地分支“3.x”一个,或者它可能没有。