总论
Github PR 虽然有着看似复杂的 UI 界面和操作流程,不过其核心在于 “如何将基于某个原仓库版本的修改正确提交” 这个基本需求上。理解了这一点,就可以理解之后的复杂逻辑了。
为什么要 fork 出一个新的仓库?
为什么我们不能直接 clone 原来的仓库并提交修改呢?为什么一定要 fork 出一个新的仓库然后再在新的仓库上提交修改呢?
这是因为我们要保证不破坏原本的仓库的基础上,还要给项目负责人展示我们的修改,让它来审核。如果我们直接在仓库上提交修改,就扰乱了原本的仓库,而如果不提交修改,那么我们该如何给项目负责人展示呢?
我们或许可以采用 mail list 的方式将补丁直接发送给负责人,似乎也可以解决问题。但是不知道为什么 Github 没有采用这种形式,或许是因为这种形式不利于我们追踪原本的仓库的变化,不利于我们将原本的仓库和我们自己的开发隔离开来。
一般而言,我们会称原本的仓库为 upstream
,而称我们 fork 出的仓库为 origin
(默认名字)。
为什么要新开一个分支进行修改?
在 fork 之后,我们往往会在 origin
的 main
上新开一个分支 feature
,然后在 feature
上进行修改,最后 pull request 到 upstream
上的 main
上。为啥不能直接在 origin
的 main
上修改呢?
其实从原理上讲,是可以的。不过我们是建议新开一个分支修改的。这是因为我们将 origin
的所有原来的分支都视为 upstream
的副本,我们随时都可以用如下命令让 origin
和 upstream
同步:
git checkout <branch-name>
git fetch upstream
git merge upstream/<branch-name>
那么如果还在一个原本的分支上进行开发,就很容易导致冲突,所以我们会选择新开一个分支。
新开一个分支的好处还可以用于同步 upstream
的其他修改,比如说我们希望在自己的 feature
分支上同步 main
的修改,可以这样操作:
git checkout feature
git rebase main