Pull Request的正确打开方式(如何在GitHub上贡献开源项目)

GitHub的官方帮助如下:

发现这个官方文档写得比较简单,并没有提到开源项目协作方式的一些必要的trick(比如建立topic branch),还有PullRequest的运作细节也没有提到。写个简单的总结补充一下。

Step 1: Fork原项目

这个不解释了,单击一下鼠标就能做到的事情。参见GitHub帮助的原文

记得用git remote add添加上游远程库的地址,否则无法追踪上游库的更新。

Step 2: 创建你的主题(topic)branch

这一步非常重要。GitHub的帮助里没有提到创建主题branch的必要性,你当然可以直接在原项目的默认branch(如master)上进行工作,但实际上:

如果打算为原项目作贡献,强烈建议你为每个主题创建一个单独的branch。

举例:如果需要修复原项目的一个和Unicode相关的issue:

$ git branch fix-unicode-error
$ git checkout fix-unicode-error

然后在自己的主题branch(这里是fix-unicode-error)下进行工作。

Step 3: 在主题branch下完成需要的工作

记得push相应的主题branch到GitHub。

*(针对贡献者)rebase还是merge

从实用的角度来讲,

  • 当你在主题branch下工作,想要导入来自上游库的(与你当前的工作不冲突的情况下)更新时,使用git rebase

例如,(假设上游branch为upstream/master)

$ git rebase upstream/master fix-unicode-error

或者直接(如果当前branch已经是fix-unicode-error):

$ git rebase upstream/master

这将把当前branch的开发“base(基础)”推进到一个新的起点,而不会引入多余的commits。

  • 当你在某个branch下工作时,git merge可以用来合并来自其他branch的更新。

如果merge的branch来自远程库,一次merge操作会增加一个额外的commit(“Merge branch 'master' of something”)。如果在一个需要发送Pull Request的主题branch下面进行这种操作,(我个人觉得)这不是一种干净的手段。

当你在主线branch(例如master)下进行开发时,git merge可以用来吸收其他开发branch引入的新特性(包括主项目维护者用来直接merge Pull Requests),很恰当。

Step 4: 发送第一个Pull Request

GitHub的界面:左边选择base branch,右边选择head branch。

  • base branch:相当于target branch,你希望Pull Request被merge到上游项目的哪个branch里。

    • 为什么要叫base branch:base可以理解为你在进行git rebase操作时的那个“base”,也就是你的主题branch所基于的开发base(基础)。
  • head branch:相当于source branch,你希望自己开发库里的哪个branch被用来进行Pull Request(当然也就是你的主题branch)。

    • 为什么要叫head branch:参见下面关于head的定义。

注意head与HEAD(大写)的区别:

  • head:简单地理解,就是指向某个commit对象的一个reference。它可以是一个branch的名称(例如,默认的master),也可以是一个tag的名称。一个库可以同时有任意多个head。

  • HEAD当前活动的head。在任意时刻,存在且仅存在一个HEAD。它可以是指向当前branch的head(比如,指向master,假如master是当前branch的话);也可以不指向任何特定的branch(这叫做detached HEAD)。

系统会从你选择的head branch(在这里,是主题branch)的这个head开始匹配所有不包含在base branch中的commits,然后自动视作你的主题branch相对于base所增加的新特性,放进同一个Pull Request中提交。

Step 5: Pull Request发送之后……

一旦你从自己的主题branch(例如fix-unicode-error)推送了一条Pull Request,那么在这条Pull Request被关闭之前,再次向这个branch里push代码,所有的commits都会被自动追加到这个Pull Request后面(不需要再另开Pull Request)。

这个功能尤其有用,比如你最初提交的Pull Request里存在某些问题,项目维护者要求你打回去修改;或者要求你给你的新feature添加一条相应的unit test(这种情况简直太常见了)。只要追加commits到你的这个主题branch中即可。

(题外话:如果原项目有Travis CI,那么它也会在每次追加push之后对Pull Request重新执行一遍测试)

*(针对项目维护者)cherry-pickformat-patcham

这几条命令主要针对项目的维护者,稍微提一下。

git pullgit merge是GitHub上最常用的merge Pull Requests的方式,在命令行下merge之后,GitHub上面的PullRequest也会相应地自动关闭。

如果贡献者一次提交了多条commits,有些是维护者并不想要的,可以用这几条命令来选择性地手动commit。(这也适用于某些项目不是借助于GitHub的Pull Request,而是通过邮件列表和patch文件来进行协作开发的情形)

在这种情况下,GitHub上面的Pull Request并不能自动关闭,需要维护者手工操作。

Step 6: Pull Request关闭之后

如果是已经被merge后关闭的Pull Request,你可以在页面的最下方找到一个“Delete this branch”的蓝色按钮。

这表明这个主题branch的历史使命已经完成(fix-unicode-error的commit已经被合并到主项目中),可以安全地从远程库中删除了。

在本地库中亦可删除这个branch:

$ git branch -d fix-unicode-error

反之,如果你的主题branch并没有被merge就被维护者关掉的话,你还可以继续再拿它来开新的Pull Request去骚扰主项目(�0�7▽‘ )。

总结

在哪些情况下可以直接使用master branch来提交Pull Request:

  • 你只想为主项目贡献某一处代码,贡献完自己的repo就可以扔的那种。
  • 你打算为主项目长期贡献代码,而且希望追随原项目的主线开发,不保留自己的特性。
  • 你打算为主项目长期贡献代码,默认master branch追随原项目主线,把自己的特性放到别的branch中。

在哪种情况下应该使用主题branch来提交Pull Request:

  • 想用master branch完全来做自己的开发。在这种情形下:

    • 会从上游库合并更新,但是这些merge本身的commits显然不可能作为返还到上游库的Pull Request的一部分。
    • 存在自己的(未被merge或者不想被merge到上游库的)commits。

鉴于Git的分布式开发哲学,每一个库均可以看作是一个独立的项目,显然是后一种(为每一个新特性建立一个专门的主题branch来向主项目推送Pull Request)的贡献方式更可取。

Pull Request的正确打开方式(如何在GitHub上贡献开源项目)的更多相关文章

  1. Pull Request的过程、基于git做的协同开发、git常见的一些命令、git实现代码的review、git实现版本的管理、gitlab、GitHub上为开源项目贡献代码

    前言: Pull Request的流程 1.fork 首先是找到自己想要pull request的项目, 然后点击fork按钮,此时就会在你的仓库中多出来一个仓库,格式是:自己的账户名/想要pull ...

  2. 如何在github上fork一个项目来贡献代码以及同步原作者的修改

    [-] 如何贡献自己的力量 如何让自己的项目与原作者的项目保持同步 作为一个IT人,通过github进行学习是最快的成长手 段.我们可以浏览别人的优秀代码.但只看不动手还是成长得很慢,因此为别人贡献代 ...

  3. 【转】如何在github上fork一个项目来贡献代码以及同步原作者的修改 -- 不错

    原文网址:http://www.cnblogs.com/astwish/articles/3548844.html 作为一个IT人,通过github进行学习是最快的成长手段.我们可以浏览别人的优秀代码 ...

  4. 如何在github上传本地项目代码

    首先你要在github上申请一个账号 网址:https://github.com/ 然后你要下载一个git工具 网址:https://gitforwindows.org/ 进入官网直接下载就行,下载完 ...

  5. 阅读GitHub源码的正确打开方式

    前言 近来发现阅读开源项目上手就整最新的代码不合适,缺少项目迭代的具体实现过程,想着若是可以看到针对问题的提交代码就好了,所以就有了本篇博客. 以文主要涉及:如何fork开源项目,如何保证本地仓库代码 ...

  6. 如何在 Github 上发现优秀的开源项目?

    之前发过一系列有关 GitHub 的文章,有同学问了,GitHub 我大概了解了,Git 也差不多会使用了,但是还是搞不清 GitHub 如何帮助我的工作,怎么提升我的工作效率? 问到点子上了,Git ...

  7. 【转载】如何在 Github 上发现优秀的开源项目?

    之前发过一系列有关 GitHub 的文章,有同学问了,GitHub 我大概了解了,Git 也差不多会使用了,但是还是搞不清 GitHub 如何帮助我的工作,怎么提升我的工作效率? 问到点子上了,Git ...

  8. (转载)如何在 Github 上发现优秀的开源项目?

    转载自:传送门 之前发过一系列有关 GitHub 的文章,有同学问了,GitHub 我大概了解了,Git 也差不多会使用了,但是还是搞不清 GitHub 如何帮助我的工作,怎么提升我的工作效率? 问到 ...

  9. 任务队列和异步接口的正确打开方式(.NET Core版本)

    任务队列和异步接口的正确打开方式 什么是异步接口? Asynchronous Operations Certain types of operations might require processi ...

随机推荐

  1. [USACO]奶牛会展(背包)

    [USACO]奶牛会展 题目背景 奶牛想证明它们是聪明而风趣的.为此,贝西筹备了一个奶牛博览会,她已经对N 头奶牛进行 了面试,确定了每头奶牛的智商和情商. 题目描述 贝西有权选择让哪些奶牛参加展览. ...

  2. 1142. Maximal Clique (25)

    A clique is a subset of vertices of an undirected graph such that every two distinct vertices in the ...

  3. Hugin

    Hugin简介 Hugin是一个开源的拼接软件,包含大量的拼接所需模块源码以及使用了部分Panorama Tools中的工具. 1)libpano13(Panorama Tools). 2)cpfin ...

  4. java中的Excel导出功能

    public void exportExcel(Long activityId, HttpServletResponse response) throws IOException { // 获取统计报 ...

  5. 触发redo写的几个条件

    触发redo写的几个条件   作者:eygle |English [转载时请标明出处和作者信息]|[恩墨学院 OCM培训传DBA成功之道]链接:http://www.eygle.com/archive ...

  6. ubuntu + JetSonNano+OpenCV3.4.8

    首先强调一点,如果要配置darknet环境,不建议安装该版本!!! 安装opencv前,建议先检测自己的系统是否已经装过其他版本, 检查方式: (1)查看是否安装opencv库: pkg-config ...

  7. BZOJ 3930: [CQOI2015]选数 莫比乌斯反演 + 杜教筛

    求 $\sum_{i=L}^{R}\sum_{i'=L}^{R}....[gcd_{i=1}^{n}(i)==k]$   $\Rightarrow \sum_{i=\frac{L}{k}}^{\fra ...

  8. POJ 2391--Ombrophobic Bovines(最大流(拆点)+二分+最短路)

    Ombrophobic Bovines Description FJ's cows really hate getting wet so much that the mere thought of g ...

  9. hud 4347 The Closest M Points(KD-Tree)

    传送门 解题思路 \(KD-Tree\)模板题,\(KD-Tree\)解决的是多维问题,它是一个可以储存\(K\)维数据的二叉树,每一层都被一维所分割.它的插入删除复杂度为\(log^2 n\),它查 ...

  10. CF889 E Mod Mod Mod——DP

    题目:http://codeforces.com/contest/889/problem/E 这题真好玩. 官方题解说得很好. 想到相邻 a[ i ] 之间的段可能可以一起维护,但是不太会. 原来是表 ...