GitHub的官方帮助如下:

  • Fork A Repo: https://help.github.com/articles/fork-a-repo
  • Using Pull Requests: https://help.github.com/articles/using-pull-requests
  • Merging a pull request: https://help.github.com/articles/merging-a-pull-request
  • Closing a pull request: https://help.github.com/articles/closing-a-pull-request
  • Tidying up Pull Requests: https://help.github.com/articles/tidying-up-pull-requests

发现这个官方文档写得比较简单,并没有提到开源项目协作方式的一些必要的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. 开发技能 | 如何在 Github 上给开源项目提交 PR?

    欢迎关注「WeiyiGeek」公众号 点击

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

    如何在github上fork一个项目来贡献代码以及同步原作者的修改 作为一个IT人,通过github进行学习是最快的成长手段.我们可以浏览别人的优秀代码.但只看不动手还是成长得很慢,因此为别人贡献代码 ...

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

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

  4. 如何在Github上为开源贡献力量?

    参与开源的一个好方式是为当前你正在使用的(开源)项目贡献力量.Github为多达五百万的开源项目提供托管.这里有各种技术集的项目,比如:recipes. HTML/CSS.Ruby.Astrophys ...

  5. 记录如何在Github上下载开源代码

    目录 下载开源项目 下载安装 git url下载 压缩包下载 下载开源项目 三种下载方式:url下载,GitHub软件下载,压缩包下载 下载安装 git 移步此篇文章,辛苦~,我才发现我总结过下载Gi ...

  6. 硬核!如何在 Github 精准搜索开源项目?

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:八个开源的 Spring Boot 学习资源,你值得拥有个人原创+1博客:点击前往,查看更多 作者:觉非 jue ...

  7. 如何在GitHub上下载开源文件

    具体实现步骤 1 . 在本地安装Git,下载地址:点击下载 2 . 下载完成后开始安装,安装过程勾选下面内容: 1. Git Bash here 2. Git GUI here 然后一直点击next, ...

  8. github可以传java吗_如何在github上传本地项目代码(新手使用)----亲测使用

    首先你要在github上申请一个账号 然后你要下载一个git工具 进入官网直接下载就行,下载完成后进入github首页,点击新项目new repository(新建),如下图所示: 然后进入如下页面, ...

  9. 如何在github上下载某个项目的单独某个目录

    github上的每一个git版本库都可以使用svn来操作,而svn是支持部分检出的,所以我们可以使用svn来下载.如果没安装svn,需要先安装一下. 例如我想下载我的practice项目的hash_t ...

最新文章

  1. C++中运算符重载的方法
  2. php三位不够前面加0,php 格式化数字 位数不足前面加0补足的实现方法
  3. 上古神器之Vim编辑器
  4. yarn install 遇到的错误消息 - Error EPERM operation not permitted, open .yarnrc
  5. DevOps 实践:千里之行
  6. (小白)函数一: 声明函数的方法—语句定义法和表达式定义法的区别
  7. python 变量赋值变成元组
  8. linux新建虚拟机到图形化界面
  9. 【优化调度】基于matlab粒子群算法求解水电厂优化调度购电最小问题【含Matlab源码 1234期】
  10. EDA365 Skill找不到Cadence安装路径的原因与解决办法
  11. 教你,用java生成验证码(这这太简单了了吧!!!!!!!)
  12. image caption
  13. 前端每日实战:66# 视频演示如何用纯 CSS 创作一台咖啡机
  14. python 球的表面积和体积_[给球的体积算表面积]C语言求球的表面积和体积
  15. java 获取IP地址 无法获取到真实的IP地址
  16. w7计算机防火墙无法更改,Win7系统电脑防火墙设置无法更改该怎么解决?
  17. scikit-image图像处理入门
  18. RISC_V(0) 指令集架构
  19. java jurisdiction_Java Region.setJurisdiction方法代码示例
  20. 【SQL必知必会】002-基础篇:了解SQL:一门半衰期很长的语言

热门文章

  1. 操作系统之文件管理:1、初识文件管理
  2. (软件工程复习核心重点)第三章需求分析习题
  3. HDOJ 杭电1874-畅通工程(Floyd算法)
  4. john工具破解密码(Linux、ZIP等)
  5. 工控蜜罐Conpot部署和入门及高级演变
  6. .Net Core----关于MVC中TempData持久化问题
  7. 如何掌握所有的程序设计语言?
  8. java native 关键字
  9. ssh : how to add hostkey to “know_hosts”
  10. Codeforces Round #402 D String Game(二分)