Pull请求是通过fork一个新的代码库用来独立开发,并将变更贡献回原始代码库。当某一个模块的开发工作完成后,可以发送一个pull请求给代码库所有者,来合并我们的代码更改。Pull请求本身可以引起合作者之间的评论,包括代码质量,功能,甚至总体战略等。

注意,一次代码提交不要包含太多内容,代码行数控制在50行以内。太长的代码行不利于审核。

一、准备工作

建议大家在Linux环境下做开发工作,毕竟这些系统线上运行时Linux是首选的环境。 GitHub使用需要先安装Git客户端,如果你已经安装了,可以忽略这一步。 请访问 https://git-scm.com/downloads来下载合适的版本。 这里以windows环境下的操作为例来说明如何工作。

二、Fork工作分支

GitHub有两种Pull请求方式:

进入GitHub的Cocolian代码库 https://github.com/cocolian,选择自己感兴趣的项目, 单击“Fork”按​​钮来创建自己的Github帐户上的代码库克隆:

github-1

访问这将在自己的帐户上创建一个该代码库的复制:

github-2

三、clone本地版本

选择 SSH URL,那样它会自动使用你自己的SSH密钥,而不用每次在git pull或者push时询问你的用户名和密码。下一步,我们将克隆一份代码库到本地计算机。 首先注意在自己的github空间下,进入cocolian上对应的项目的分支。选择SSH方式,点击右侧按钮复制地址: github-3

在本地建立一个工作文件夹,比如d:\workspace,用来做开发工作。在windows下,用Git Bash,对应的地址是/d/workspace

admin@admin-PC MINGW64 /d
$ cd workspace/

admin@admin-PC MINGW64 /d/workspace
$ git clone git@github.com:shamphone/jigsaw-payment.git
Cloning into 'jigsaw-payment'...
remote: Counting objects: 1353, done.
remote: Compressing objects: 100% (171/171), done.
remote: Total 1353 (delta 117), reused 208 (delta 63), pack-reused 1063
Receiving objects: 100% (1353/1353), 3.49 MiB | 54.00 KiB/s, done.
Resolving deltas: 100% (429/429), done.
Checking out files: 100% (233/233), done.

一般情况下,每一个新的功能,我们将创建一个新的Git分支。这是一个很好的做法,因为在未来,如果经过一番讨论后我们需要进一步更新分支,Pull请求将被自动更新。

以下以修改Readme文件为例,介绍如何建立分支来完成这个任务。


admin@admin-PC MINGW64 /d/workspace
$ cd jigsaw-payment/

admin@admin-PC MINGW64 /d/workspace/jigsaw-payment (master)
$ git checkout -b update-readme
Switched to a new branch 'update-readme'

注意,必须确保是在jigsaw-payment这个工作目录下,之后在路径后会显示当前的分支。/d/workspace/jigsaw-payment (master)

在为这个新功能增加文件后,我们只需要将修改提交到这个新分支上,然后切换回master分支:

admin@admin-PC MINGW64 /d/workspace/jigsaw-payment (update-readme)
$ git add .

admin@admin-PC MINGW64 /d/workspace/jigsaw-payment (update-readme)
$ git commit -m 'update readme file'
[update-readme 4035813] update readme file
 1 file changed, 1 insertion(+)

admin@admin-PC MINGW64 /d/workspace/jigsaw-payment (update-readme)
$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.

在这里,我们需要将新分支推送到远程代码仓库里。首先,我们需要检查这个新功能的分支名称以及其在远程仓库的别名,然后我们用git push [git-remote-alias] [branch-name]推送这个变更。

admin@admin-PC MINGW64 /d/workspace/jigsaw-payment (master)
$ git branch
* master
  update-readme

admin@admin-PC MINGW64 /d/workspace/jigsaw-payment (master)
$ git remote -v
origin  git@github.com:shamphone/jigsaw-payment.git (fetch)
origin  git@github.com:shamphone/jigsaw-payment.git (push)

admin@admin-PC MINGW64 /d/workspace/jigsaw-payment (master)
$ git push origin update-readme
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 331 bytes | 331.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:shamphone/jigsaw-payment.git
 * [new branch]      update-readme -> update-readme

进入我们fork的代码库的GitHub页面,选择为这个新功能建立的分支,然后点击Pull Request按钮: github-4

提交Pull请求后,页面将直接跳转到原始库的Pull请求页面,我们将看到我们提交的Pull请求,作为一个新的问题,以及作为一个新的pull请求。 github-5

在经过讨论后,fork的代码库的作者可能想为这个新功能增加一些新的改动。在这种场景下,我们需要在本地计算机上checkout这个同样的分支,修改,提交,并推送回GitHub。当我们再次访问原代码库的pull请求页面的时候,会发现上次提交的Pull请求已经自动更新了。

四、 代码评审

有审核权限的用户进入系统后,可以执行代码审核。

五、合并一个Pull请求

如果你是代码审核人员,你将有两种方式来合并收到的Pull请求。

直接在GitHub上合并:如果我们想直接在GitHub上进行合并,必须确保没有冲突。原始库的所有者可以通过简单地点击Merge Pull Request按钮来进行合并: github-6

在本地计算机上进行合并:另外一种情况,合并的时候可能会遇到冲突,点击上部的Info图标,GitHub有非常清晰的指导,怎么从贡献者的分支上下拉代码变更到本地,合并并解决冲突。

六、同步远程库

当代码合并到jigsaw-projects的主库之后,版本就变得复杂起来了:

  1. 本地的update-readme分支,是最新的代码。(假设没有其他人在更新这个分支)
  2. 本地的master和个人github上的master一样,是修改之前的代码。
  3. 主库,也就是远程的jigsaw-projects上的jigsaw-payment-docs项目代码,和1一样,都是最新的代码。

这样,我们就需要更新本地master和个人github上的master代码,让他们和jigsaw-projects主库的最新代码保持一致。

首先,我们需要设置一下主库来作为个人github分支这个从库的上游。

 git remote add upstream git@github.com:jigsaw-projects/jigsaw-payment-docs.git

看一下现在的库的情况:

$ git remote -v
origin  git@github.com:shamphone/jigsaw-payment-docs.git (fetch)
origin  git@github.com:shamphone/jigsaw-payment-docs.git (push)
upstream        git@github.com:jigsaw-projects/jigsaw-payment-docs.git (fetch)
upstream        git@github.com:jigsaw-projects/jigsaw-payment-docs.git (push)

抓取主库的信息到本地:

$ git fetch upstream
remote: Counting objects: 1, done.
remote: Total 1 (delta 0), reused 1 (delta 0), pack-reused 0
Unpacking objects: 100% (1/1), done.
From github.com:jigsaw-projects/jigsaw-payment-docs
 * [new branch]      master     -> upstream/master

注意,这个变更被同步到 upstream/master这个分支了。

切换到master分支

$ git checkout master

将upstream/master分支合并到主干master。 如果本地没有更新,则会执行fast-forward。

$ git merge upstream/master
Updating e58f17a..90c18ac
Fast-forward
 dev/_posts/2017-10-15-function-list.markdown | 158 +++++++++++++++++++++++++++
 1 file changed, 158 insertions(+)
 create mode 100644 dev/_posts/2017-10-15-function-list.markdown

注意,到目前为止,只是将你的本地的master同步到最新版本,如果需要更新个人github上的分支,需要执行push操作

$ git push origin master
Counting objects: 1, done.
Writing objects: 100% (1/1), 281 bytes | 281.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To paymentrpc:paymentrpc/jigsaw-payment-docs.git
   e58f17a..90c18ac  master -> master

如上,如有问题,请大家及时在微信群里沟通。