Lawrence.


Pull Request


What and How.


Pull Request 是 GitHub 发明的用于 Git 多人协作开发的模式。

官方文档里有不少详细的定义: GitHub Docs

我画了一个简单的示意图解释具体的行为:

Pull-Request

以下是我自己的认识:

首先,存在一个上游(upstream)仓库,仓库地址一般的 URL 都是类似 REST 样式的路径,比如:

github.com/kubernetes/website

第一个路由为仓库的拥有者,第二个路由为项目名。上面的 URL 可以非常形象地理解为:

托管在 GitHub 上面的由 Kubernetes 作者开发的 website 项目。

然后,我们采取 fork (复刻)动作来将 upstream 仓库此刻的代码复制到自己的仓库中,于是产生了源(origin)仓库,地址类似于:

github.com/Lonor/website

现在,可以使用如下命令来获取到 origin 代码到本地:

git clone git@github.com:Lonor/website.git

OK! 我们已经一步一步拿到了代码,用 IDE 打开这个仓库,不着急更改内容,先看一下本地仓库关联了哪些远程仓库,使用如下命令查看:

git remote -v

它至少会返回我们 clone 的仓库地址。但是并没有呈现出 upstream 地址,我们需要手动添加:

git remote add upstream git@github.com:kubernetes/website.git

这时候就关联好了,这一步很关键:因为会牵涉到多人协作时发生的同步复刻 (Sync fork)。

现在尝试修改代码,比如修复某个臭虫(俗称 bug),或者增加某种需要的功能。然后,以 master 分支为例,push 到 origin:

git add .
git commit -m "bug fixed"
git push -u origin master

现在,刷新远程仓库 Web 端页面,可以发现代码已经提交好了。接下来,创建 Pull Request (拉取请求)。

#如何理解 Pull Request?

我们所做的是向 upstream 仓库贡献自己写的代码,为什么叫 Pull Request 而不叫 Merge Request 呢?这样理解,本质是对的。GitLab 就采用了 Merge Request 的叫法。但是 GitHub 认为,origin 仓库开发者并没有权限直接向 upstream 仓库直接提交代码,但是,origin 仓可以向 upstream 发一个请求,让 upstream 仓库主动拉取 origin 仓库的变更代码,以此实现合并的目的。

欲了解更多,可以参考知乎上有关 Pull Request 的讨论

现在 Pull Request 创建好了!它会在 upstream 仓库的 Pull Requests 页面下出现,URL 一般长这样:

github.com/kubernetes/website/pull/21198

这个过程非常有用!尤其对于持续集成能产生很大的效率。

我理解的 Pull Request 本质上是一个分支,归到底还是一个指向某一系列提交之首的指针或引用

使用如下命令可以在本地仓库切到 GitHub 上 233 的 Pull Request 合并前或合并后的 commit Head:

git config remote.origin.fetch '+refs/pull/*:refs/remotes/origin/pull/*'
git fetch
git show-ref
# Pull Request 合并之前
git checkout origin/pull/123/head
# Pull Request 合并之后
git checkout origin/pull/123/merge

这样就能够在某个 PR 上做一些集成测试了。

#Merge

在 GitHub 上合并 Pull Request 有三种方式:Merge、Squash 以及 Rebase. 主要区别:

  • Merge: 除了 PR 上所有的 commit,merge 时会再 commit 一次
  • Squash: 将 PR 上所有的 commit 压缩成一次 commit
  • Rebase: 执行变基操作后追加到被合并分支

直接 Merge 是大多数人的选择,但是我自己偏好使用 Rebase,这种做法会保持主分支的干净简洁。

今天先到这里,有空继续写。