Git教程——如何在github上为开源项目提交PR?

Posted by Mr.Zhou on April 23, 2019

背景

最近经常接触到几个开源项目,而且都已接入生产环境,在使用过程中发现了一些问题,觉得很有必要提出来,必要时对其进行调整,合并至原始项目。

而在合并过程中,自然涉及到了如何使用git进行代码合并,初次使用会遇到一些问题,这边在填完坑后,总结了下pr的完整流程,以供参考。

我们大部分的操作是在命令行下进行的,有些朋友可能会使用ide中集成的git插件进行pr,其实原理基本都是一样的,理解了命令行,图形界面更不在话下了。

pr内容

我们针对gohangout这个项目的README.md文件进行修改,我们需要修改编译参数,以解决gohangout在容器内无法正常运行的问题。

操作过程

  1. 找到原始项目,对其进行fork:

现在我想要为这个项目提交代码,但我并不是这个项目的项目成员,所以只能够以fork的方式进行pr。

在原始项目中点击fork按钮,github会自动生成一个属于我们自己的项目,我得到的项目地址是:gohangout

  1. git clone自己的项目仓库到本地:
$ git clone https://github.com/zhoufwind/gohangout.git
$ cd gohangout
  1. 在master分支添加原始仓库为上游分支:
$ git remote add upstream https://github.com/childe/gohangout.git
$ git remote -v
origin	https://github.com/zhoufwind/gohangout.git (fetch)
origin	https://github.com/zhoufwind/gohangout.git (push)
upstream	https://github.com/childe/gohangout.git (fetch)
upstream	https://github.com/childe/gohangout.git (push)

注意如果之前已经clone下来,如果很久没进行同步,或是原始项目更新频率较高,会导致我们fork的项目落后于原始项目,在我们fork后的github页面会有如下提示:This branch is 10 commits behind childe:master.

img

这个时候需要将自己项目仓库同步至原始仓库最新版本,以避免冲突:

$ git pull upstream master
$ git push origin master:master

拉去最新代码后,提示:This branch is even with childe:master.,表示fork的项目已经和原项目保持一致了。

img

  1. 在原项目中创建issue,在原项目中报告你所遇到的问题。

我们便在原项目中提交了问题issue

  1. 在自己fork的项目新建分支
$ git checkout -b iss28_doc_add-go-make-detail

可以确认下当前分支是否已经切换至新建的分支下:

$ git branch

注:想要规范创建分支名,可以参照Git 分支 - 分支的新建与合并这篇文档,文档对分支的创建有比较详细的介绍。

  1. 修改原项目代码并提交

在刚新建的分支下进行代码修改,确认修改完毕后进行commit:

$ git add README.md
$ git commit

注:想要规范填写commit内容,可以参照如何优雅地pull request这篇文章,文章对commit的格式有比较详细的说明。

我们的commit内容如下:

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch iss28_doc_add-go-make-detail
# Changes to be committed:
#       modified:   README.md
#

<doc>: 避免因go编译环境问题导致gohangout在docker容器中运行失败[issue 28]

编译go代码时,默认`CGO_ENABLED=1`,Go代码中如调用C代码,会进行cgo,对外部有依赖(动态链接),而在Alpine linux这个基础docker镜像下运行可能造成兼容性问题,所以推荐编译时指定`CGO_ENABLED=0`,go采用纯静态编译
,编译出来是纯静态的go程序,不会出现外部库依赖问题。

Issue #28
Close #28
  1. 提交分支,申请pr

接下来就可以上传我们本地的分支了,命令如下:

$ git push --set-upstream origin iss28_doc_add-go-make-detail

此时访问我们fork的项目首页,会发现git已经监测到我们刚提交的分支代码,并询问我们是否需要提交pr:

img

我们点击“Compare & pull request”后发现,git已经自动把刚才我们commit的内容拷贝到了pr的备注:

img

我们点击“Create pull request”,此时便发起了pr,等待原项目成员审核及回复,状态可在原项目中看到:

img

  1. pr通过后,更新fork项目master并删除分支:

管理通过pr后,项目状态如下:

img

更新fork项目,并且删除分支:

$ git branch
$ git checkout master

$ git pull upstream master
$ git push origin master:master

$ git branch -av
$ git branch -d iss28_doc_add-go-make-detail
$ git push origin :iss28_doc_add-go-make-detail

此时fork项目恢复至初始状态。