【转】GitHub 从单机到联机:玩转 Pull Request

最近在参与一个叫 Exercism 的项目,这是一个由 GitHub 生态工程师 Katrina Owen 发起的编程练习社区,提供了超过50门语言的练习。作为用户,你仅需使用命令行工具即可下载和提交练习,提交后还可以和社区中其他学习者交流讨论。

Exercism的社区互动性

在和世界各地的小伙伴们愉快地玩耍了十来天之后,我觉得可以为这个社区贡献些什么。由于我比较擅长 Python,所以决定为 exercism/python 这个仓库贡献代码。我知道很多朋友都是在“单机模式”下使用 GitHub ——一个人默默地维护自己的仓库,却始终没有和他人互动乃至协作过。接下来我将分享第一次踏入开源世界、“联机”使用 GitHub 的体验,并将对应 GitHub Flow 手把手教会你怎么提交 Pull Request(下面简称 PR )。

在阅读本文前,希望你已经具备以下条件:

  1. 已经安装好 Git,能够用命令行进行基本的 Git 操作。如果不熟悉 Git,你可以看一下廖雪峰的 Git 教程;如果你对自己的英文有自信,那么 Learn Git Branching 这个互动教程一定会让你受益更多!

  2. 已经注册一个 GitHub 帐号,并对 GitHub 的一些基本概念(例如仓库,Issue,还有我们讨论的核心 PR)有所了解。

  3. 拥有一颗在开源社区呼风唤雨的雄心壮志(手动滑稽)。

寻找值得解决的 Issue

通常,贡献的第一步是寻找值得解决的 Issue。选择正确的 Issue 并不简单,除了力所能及,还要看一下有没有人已经在解决这个问题。你可以看一下这个 Issue 是否有人已经回复打算解决,或者在 Pull Requests 列表中搜索一下有没有人已经在解决,否则真的就是在浪费宝贵的时间。

选择合适的 Issue

这里我们选择解决 rational-numbers: implement exercise,任务就是实现一个新的练习,名为 rational-numbers。之所以选择这个 Issue,是因为仓库维护者很认真地把实现新练习的详细步骤都告诉了我们,而且也没有其他人领这个任务。于是我们回复一句“I'll work on this”,既是通知维护者,也是告诉其他人我们已经负责解决这个 Issue,请不要重复劳动。

好了,开始动手吧!

准备工作

第一步:Fork原仓库

在页面右上角点击 Fork 按钮,随后就生成了属于你的仓库。

上图:Fork 原仓库

上图:Fork 来的仓库

为什么要先 Fork 别人的仓库呢?不能直接把 exercism/python 直接 clone 到本地吗?

如果你只是打算阅读别人的源代码,这样做当然是可以的,然后每次你只需要 git pull 就可以获取最新的代码了。但如果你打算贡献代码就不能简单地 clone 了。由于你不具备 exercism/python 的 write access(写入权限),因此你就无法使用 git push 来推送你的修改,这时候就只能 Fork 到自己的帐号下,GitHub 会为你生成 mRcfps/python(mRcfps 是我的 GitHub 用户名)。对于这个 Fork 来的仓库,你就拥有了所有的权限(克隆、修改甚至是删除仓库)。这时候就可以进行任何想要的修改了。

第二步:将 Fork 来的仓库 clone 到本地

在命令行中输入下面的命令:

$ git clone https://github.com/mRcfps/python.git

第三步:创建新分支

GitHub Flow:创建新分支阶段

这一步是最容易被忽视的一步,却恰恰是正式开始贡献的第一步。

 

$ git checkout -b impl-rational-numbers

这里我创建了一个新的分支 impl-rational-numbers,意思就是 implement (exercise) rational numbers。在创建分支时要尽量保证易于记忆、易于辨认,这样做有两点好处:

  • 在多个分支上切换工作时会方便很多
  • 在提交 PR 后便于仓库主进行维护

一个需要思考的问题是,为什么需要开新的分支?不能直接在 master 分支上修改吗?

先给出简单的回答:能,但是非常非常不推荐。

根据 GitHub Flow 的定义,master 分支应当确保始终是可部署的(deployable),所以在 master 分支上进行开发和尝试是非常不推荐的做法。而且 GitHub 的 PR 都是以分支为单位的,如果你选择 master 分支进行开发,那么当你想要解决另一个 Issue 的时候就会变得非常棘手(熟悉 Git 的朋友也许会说可以通过回退节点再开新分支,但是那样分支管理就会变得一团糟)。

贡献代码

GitHub Flow:贡献代码阶段

这里就不展示全部的工作了,具体代码变化请参考这里。

 

$ git status
On branch impl-rational-numbers
Changes not staged for commit:(use"git add <file>..."to update what will be committed)(use"git checkout -- <file>..."to discard changes in working directory)modified: config.jsonmodified: exercises/rational-numbers/example.pymodified: exercises/rational-numbers/rational_numbers.pymodified: exercises/rational-numbers/rational_numbers_test.pymodified: exercises/rational-numbers/README.mdno changes added to commit (use "git add" and/or "git commit -a")

好的,然后我们进行 commit:

 

$ git commit -am "rational-numbers: implement exercise"

提交工作

GitHub Flow:提交 PR 阶段

接下来就是激动人心的时刻:提交我们贡献的代码!

首先,我们需要把修改提交到 mRcfps/python ,也就是我们自己的远程仓库。

 

$ git push -u origin impl-rational-numbers

选项 -u 等同于 —set-upstream。impl-rational-numbers 就是我们刚才进行修改的分支。然后,我们打开 mRcfps/python,也就是我们 Fork 来的仓库,会看到一点小小的变化:

Fork 来的仓库自动检测到新提交的分支

实际上如果你打开 exercism/python 的页面也会出现这样的提示。然后点击按钮 Compare & pull request,开始编辑我们的 PR:

编辑 PR 信息

这里要说明一下 GitHub 关键词:当使用 fix(es),close(s) 或 resolve(s) 时,如果这个 Pull Request 被合并,会自动关闭对应的 Issue。这里我标出了 Closes #1300,那么当我们贡献的代码被接受时,就会关闭 rational-numbers: implement exercise 这个 Issue。正确地使用 GitHub 关键词能够极大地方便仓库维护者,他们就不需要去查找对应的是哪个 Issue 并去手动关闭它了。

点击 Create pull request,进行提交!

讨论和评审

GitHub Flow:评审讨论阶段

接下来就是等待。第二天起来发现仓库维护者回复我们了。

维护者进行了代码评审

他指出我们修改的 config.json 有问题,并给出了修改建议。至于他手抖一不小心 approve 我们的修改就不必在意了(再次手动滑稽)。

按照他的建议修改好之后,我们提交新的修改。

 

$ git commit -am "rational-numbers: fix topics in config.json"
$ git push

可以打开 PR 页面查看我们新的修改。

新的修改出现在 Pull Request 页面

部署阶段

GitHub Flow:部署阶段

仓库维护者同意了我们的修改!

维护者部署了我们的修改

然后他将 exercism/python 的 master 分支并入了我们的 impl-rational-numbers 分支。他为什么要这么做呢?因为当我们在这个分支上工作时,exercism/python 的 master 分支上可能提交了新的修改,导致我们的分支并不是最新的。

master 上新的修改使我们的分支过时

通过将 master 分支并入我们的分支,我们的分支就能进入即将部署(Ready to Deploy)状态了。如果这时候 CI (持续集成,会在后面讲到)报错,这就说明我们的分支还不能部署,还需要进一步修改甚至是回滚。但是这里,我们合并后的分支通过了 CI 的测试。

合并阶段

GitHub Flow:合并阶段

维护者紧接着就将我们的分支正式并入了 exercism/python 的 master 分支,这意味着我们的 PR 画上了圆满的句号,我们的贡献真正地进入到了原仓库!

维护者合并了我们的分支

由于 impl-rational-numbers 已经合并,可以安全删除,所以我们点击 Delete branch 按钮,删除我们远程仓库 mRcfps/python 中的分支。然后在本地输入下面的命令,删除本地分支:

 

$ git checkout master
$ git branch -D impl-rational-numbers

这里为什么使用 -D 进行强制删除呢?因为 impl-rational-numbers 在本地并没有与 mRcfps/python 的 master 分支合并(不要绕晕了,刚才我们只是和 exercism/python 的 master 进行了合并)。我们自己的 master 分支推荐用下面介绍到的方法进行同步。

一些补充

关于 PR 生命周期的介绍就到此结束了。接下来我会讲一些相关的较为重要的地方。

保持 Fork 来的仓库同步

如果其他的贡献者向 exercism/python 提交代码,或者是我们自己提交的代码,我们的 mRcfps/python 就会过时。要经常保持我们 Fork 来的仓库与原仓库同步,这样能尽可能地降低冲突发生的概率。接下来还是以我们 Fork 来的仓库 mRcfps/python 为例,来与 exercism/python 保持同步。

首先,查看 mRcfps/python 有哪些远程仓库。这里应该只有 origin。

 

$ git remote -v
origin  https://github.com/mRcfps/python.git (fetch)
origin  https://github.com/mRcfps/python.git (push)

然后,将 exercism/python 添加进我们的 remote 仓库中,将其命名为 upstream(当然也可以取其他名字,但是按照惯例会更加方便)。

 

$ git remote add upstream https://github.com/exercism/python.git

再看看 remote 列表中是不是多了些什么……

 

$ git remote -v
origin  https://github.com/mRcfps/python.git (fetch)
origin  https://github.com/mRcfps/python.git (push)
upstream        https://github.com/exercism/python.git (fetch)
upstream        https://github.com/exercism/python.git (push)

upstream 已经在 remote 列表中!然后我们就可以轻松地进行同步了。先确保当前处在 master 分支上,然后获取 upstream 的修改,再并入我们本地的 master 分支。

 

$ git checkout master
$ git fetch upstream
$ git merge upstream/master

再把本地的更新 push 到 origin,也就是我们的 GitHub 仓库:

 

$ git push

同步工作完成!

持续集成

很多开源项目都会通过持续集成(Continuous Integration,简称 CI)来确保代码质量。对于我们贡献者来说,这意味着每次提交 PR 和继续 push 代码,CI 都会对我们的提交进行构建并执行仓库维护者指定的检查,例如代码风格检查、单元测试等等。

如果你查看你新提交的 PR,你会发现右上角有个黄色的圆圈,这表示 CI 正在检查你的提交。

CI 正在检查我们的 PR

当右上角的黄色圆圈变成绿色的勾,就表示你的代码通过了 CI !

这个 PR 通过了 CI

有时候会出现红色的叉,表示未通过 CI 测试。

这个 PR 未通过 CI

这时候我们就需要进入 PR 页面,翻到最下面,查看 Travis-CI (这个仓库使用的是流行的 Travis CI)检查的详细信息,找出错误原因后进行修改,然后 git push 提交我们的修改即可,直到通过 CI。

总结

可能步骤有点复杂,所以这里总结一下 Pull Request 的生命周期 :

  1. 确定要贡献的项目,寻找值得解决的 Issue。

  2. 将原仓库 Fork 到自己的帐号下,然后克隆到本地。

 

$ git clone https://github.com/<YOUR_USERNAME>/<FORKED_REPO>.git
  1. 开启新分支,修改代码并提交。

 

$ git checkout -b <NEW_BRANCH_NAME>
$ git commit -am "<COMMIT_MESSAGE>"
$ git push -u origin <NEW_BRANCH_NAME>
  1. 打开仓库的 GitHub 页面,点击提示的 Compare & pull request 按钮,填写 PR 信息(记得使用 GitHub 关键词关闭对应的 Issue)然后提交。

  2. 如果 CI 测试未通过,或者仓库维护者要求修改(request changes),那么就在本地继续修改代码,然后 git push 再次提交,直到通过 CI 和仓库维护者的评审。

  3. 仓库维护者部署和并入你的分支,贡献完成。

亲自实践

这篇文章的 GitHub 仓库在这里,你可以随意地发起 Issue 或 Pull Request。如果你只是想要亲自实践一下上面所讲的内容,就请在 THOUGHTS.md 中随意写下你的想法并提交给我,我会尽快合并你的分支。当然如果你对本文有改进意见,那更欢迎你的 Pull Request,让这篇文章变得更好!



作者:图雀社区
链接:https://www.jianshu.com/p/ac33f0295629
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436973.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【转】GitHub客户端操作1--仓库相关操作github团队协作流程

1、创建仓库 点击“”&#xff0c;点击Create,然后填写Name为my&#xff0c;点击Create repository&#xff0c;即可创建一个my仓库 2、从本地仓库存放位置&#xff0c;添加test仓库到GitHub客户端 点击“”&#xff0c;点击Add,然后点击Browse&#xff0c;选择仓库存放位置&a…

【转】GitHub客户端操作2--分支操作

简单分支操作 &#xff08;1&#xff09;创建新分支&#xff1a;my分支 备注&#xff1a;新创建的分支&#xff1a;my分支里面的内容是和master分支里面的内容是完全一样的。 &#xff08;2&#xff09;删除my分支 &#xff08;3&#xff09;修改my分支【在my分支上进行项目内…

【转】GitHub客户端操作3--pull Request(拉请求)

一、参考说明 参考文章一&#xff1a;Github上提交代码(pullrequest) 网址&#xff1a; https://jingyan.baidu.com/article/358570f64dcdc2ce4724fc32.html 参考文章二&#xff1a;GitHub——Pull Request 网址&#xff1a;http://blog.csdn.net/u012325167/article/detai…

【转】GitHub上README.md教程

本文是转载文章&#xff0c;文章的来源&#xff1a;csdn博客 博主&#xff1a;果冻虾仁 文章&#xff1a; GitHub上README写法暨GFM语法解读 博文地址&#xff1a;https://blog.csdn.net/guodongxiaren/article/details/23690801 转载请保留原作者guodongxiaren的原文地址&…

【转】WPF单位真的与分辨率无关吗?

转载自http://www.cnblogs.com/helloj2ee/archive/2009/04/21/1440709.htm WPF从发布之日起&#xff0c;一直将“分辨率无关(resolution independence)”作为其亮点&#xff0c;声称使用WPF制作的用户界面在轻巧的Ultra-Mobile PC的屏幕上和在50英寸的电视机上都能很好地显示。…

【转】世上最简单的vue教程

一、需要了解的基本知识 node.js Node.js是一个Javascript运行环境(runtime)&#xff0c;发布于2009年5月&#xff0c;由Ryan Dahl开发&#xff0c;实质是对Chrome V8引擎进行了封装。Node.js对一些特殊用例进行优化&#xff0c;提供替代的API&#xff0c;使得V8在非浏览器环境…

工程师学乐理(一)尝试理解音乐

前言 很早就接触了乐理&#xff0c;但是一直没有学懂&#xff0c;越学问题越多。个人感觉&#xff0c;其中很大的原因是有关教材写得看不懂&#xff0c;用未知的东西描述未知的东西&#xff0c;不知所云。前几年还买了一把吉他&#xff0c;买了课程&#xff0c;断断续续学了几…

【转】Vue.js入门教程(一)从静态页面到前后端分离开发

第一章&#xff1a;基础知识 我能看懂吗&#xff1f; 只要你现在能用htmlcssjs制作一个静态页面&#xff0c;相信我&#xff0c;你100%可以读懂这篇文章。 本文尤其适合那些想要了解前后端分离开发技术&#xff0c;或者刚刚脱离传统MVC开发模式的前端人员。 回想一下&#xf…

工程师学乐理(二)音阶及倾向性

前言 阅读本文前&#xff0c;请先阅读《写给理工科人看的乐理》。 本文主要讲音阶。在其他地方能查到的细节&#xff0c;我们这里就不会多说了。本文重点在于梳理音阶背后的逻辑&#xff0c;尝试把技术点串起来讲。 没有逻辑的东西是咱们工程师比较讨厌的&#xff0c;任何大自…

【转】VS工具:实时可视化树

VisuaStudio号称全宇宙最强大的IDE。在VS2015版本中&#xff0c;微软又给广大开发者带来了一个强大的工具&#xff1a;实时可视化树(Live Visual Tree&#xff0c;以下简称可视树)。其实树可视化工具并不是新鲜的东西&#xff0c;在WPF的时候就有了&#xff0c;只是这次微软集成…

【转】WPF 入门《常用控件》

1.GroupBox 注意: GroupBox仍然需要布局容器来放置元素。如: StackPanel面板 1 2 3 4 5 6 7 <GroupBox Header"select number?"> <StackPanel> <RadioButton>one</RadioButton> <RadioButton>two</…

【转】wpf从我炫系列1----布局控件的使用(上)

今天我来给大家讲解在学习WPF过程中使用布局控件的一些心得&#xff0c;主要给大家介绍一下一个控件的用法。希望对大家学习Wpf有所帮助. 1. StackPanel栈面板 2. WrapPanel环绕面板 3. DockPanel停靠面板 4. Grid网格 5. UniformGrid均布网…

【开源项目】EasyCmd命令图形化软件

EasyCmd 项目地址&#xff1a;https://gitee.com/showmework/EasyCmd 最新版本&#xff1a;v0.2预览版 介绍 命令行图形化。 让命令行更易于使用&#xff0c;从命令行复杂的参数及语法中解放出来。 设计思想 软件设计思想并不是构建用户界面&#xff0c;现代操作系统已经…

php在线读取pdf文件大小_PDF转WORD在线转换器哪家强?

无论是工作还是日常生活中&#xff0c;经常需要将pdf转换成word文档进行编辑&#xff0c;我想大部分人一定是和我一样&#xff0c;首先会去找度娘帮忙&#xff0c;百度一下“pdf转word”出现了很多在线转换器&#xff0c;比如大家常用的讯捷、smallpdf等&#xff0c;然后立马进…

【转】wpf从我炫系列2----布局控件的使用(下)

4. GRID控件 Grid控件可以是说是wpf中功能最强大和使用最多的控件。它有点类似于HMTL网页布局中的表格&#xff0c;可以自定义行列显示&#xff0c;并可以合并某些行和列. 使用<Grid.RowDefinitions>可以定义GRID中的行数&#xff0c; 使用<Grid.ColumnDefi…

【转】WPF从我炫系列3---内容控件的用法

今天我来给大家讲解WPF中内容控件的用法&#xff0c;在WPF中的内容控件&#xff0c;通俗的讲&#xff0c;是指具有Content属性的控件&#xff0c;在content属性里面可以嵌套放置任意其他类型的控件&#xff0c;但是Content只能接受单个元素&#xff0c;可以通过布局控件来组合放…

【转】WPF从我炫系列4---装饰控件的用法

在这一节的讲解中&#xff0c;我将为大家介绍WPF装饰控件的用法&#xff0c;主要为大家讲解一下几个控件的用法. ScrollViewer滚动条控件 Border边框控件 ViewBox自由缩放控件 1. ScrollViewer滚动条控件 大家知道在WPF中的一些布局控件中是不带滚动条的&#xff0c;如果里面…

windeployqt.exe的使用与避坑(windows平台)

1. 介绍 windeployqt.exe是Qt自带的工具&#xff0c;用于创建应用程序发布包。 简单来说&#xff0c;这个工具可以自动地将某程序依赖的库、资源拷贝到其所在目录&#xff0c;防止程序在其他电脑上运行报找不到库的错误。 这里贴上官方文档&#xff1a;https://doc.qt.io/qt-5…

【转】WPF从我炫系统5---基本控件的用法

今天我来给大家讲解WPF中一些基本控件的用法&#xff0c;所谓基本控件&#xff0c;就是我们最常用用到的一些控件&#xff0c;通过这一节的讲解&#xff0c;大家会对WPF中的控件的用法有一个更深入的了解。 1. 基本控件 LABEL控件 Label控件是我们最熟悉的控件&#x…

【转】在WPF中自定义控件

周银辉的开发博客(WPF) 在WPF中自定义控件(1) 一, 不一定需要自定义控件 在使用WPF以前,动辄使用自定义控件几乎成了惯性思维,比如需要一个带图片的按钮,但在WPF中此类任务却不需要如此大费周章,因为控件可以嵌套使用以及可以为控件外观打造一套新的样式就可以了.是否需要我们…