读书笔记 | GitHub入门与实践3
本篇是 <<GitHub入门与实践>> 第8-10章节 和附录 A B的笔记
第八章 与GitHub相互协作的工具及服务
GitHub 的诞生并不单单影响到了软件开发的相关人员。现在的GitHub 已经真正成为了一个Hub,与其相互协作的工具和服务层出不穷。下面让我们为各位介绍几个比较常用的服务。
hub 命令
在使用GitHub 的过程中,会不可避免地频繁接触到git 命令。而我们在这里介绍的hub 命令A 则是一个封装了git 命令的命令行工具,能够辅助用户使用GitHub。这是个很方便的工具,经常使用GitHub 的读者请务必一试。
概要
hub 命令是由Chris WanstrathB 带头开发的软件。在hub 命令仓库的README.md 文件中,我们可以看到“git + hu= github”这样一句话C。正如这句话所说, hub 命令将通常的git 命令进行封装并增加几项功能,就可以调用GitHub API 发送命令。由于其封装了git 命令,所以能够执行所有git 命令的操作。另外通过hub 命令功能还得到了扩展,比如指定GitHub 端仓库时可以用简略路径替代完整路径等。具体的命令我们将在后面详细讲解。
安装
hub是github推出的git命令行扩展,可更方便的用命令行使用GitHub
可以参考https://blog.csdn.net/weixin_36270908/article/details/98961631
这里不详细展开了
Travis CI
Travis CIA 是一款免费服务,专门托管面向开源开发组织的CI(Continuous Integration,持续集成)。CI 是XP(Extreme Programming,极限编程)的实践之一。近年来人们普遍使用Jenkins 等软件来实现这一目的。让CI 软件监视仓库,可以在开发者发送提交后立刻执行自动测试或构建。通过持续执行这样一个操作,可以检测出开发者意外发送的提交或无意的逻辑偏差,让代码保持在一定质量以上。如果各位正在通过GitHub 发布代码,建议使用Travis CI。Travis CI支持Ruby、PHP、Perl、Python、Java、JavaScript 等Web 相关的语言.
相关链接
http://travis-ci.org/
http://about.travis-ci.org/docs
实际尝试
现在让我们来设置自己的仓库,让它可以使用Travis CI。一般情况下,只要在仓库中添加.travis.yml 这样一个Travis CI 专用的文件,Travis CI 就与GitHub 集成了。
编写配置文件
我们以在Ruby on Rails 上应用RSpec 为例,编写.travis.yml 文件。
language: ruby
rvm:
- 1.9.2
- 1.9.3
script: bundle exec rspec spec如上所述,按照
所使用语言
版本
执行测试的相关命令
的顺序描述。如果一次描述多个版本,则会以每个版本分别进行测试。这样一来,用户可以迅速检测出代码在哪些版本下无法通过测试。如果各位使用其他种类的语言,请参考官方网站的相关文档A。基本的设置方法不变。将这个文件放置到仓库的路径下再push 给GitHub端,我们就基本完成了使用Travis CI 的准备工作。
检测配置文件是否有问题
Travis CI 专门提供了Travis WebLint 供用户检测.travis.yml 文件是否存在问题B。检测时只需指定仓库,如果发现问题会出现图8.1 中的页面。
与GitHub集成等等
更多内容自行搜索 不继续深究了
Coveralls
概要
CoverallsA 是由Lemur Heavy IndustriesB 运营的代码覆盖率检测服务。借助Travis CI 或Jenkins 等持续集成服务器,向用户报告自动测试的测试覆盖率(图8.6)。

该服务支持Ruby/Rails、Python、PHP、JavaScript/Node.js、C/C++、Java、Scala 等语言。详细内容请查看官方网站的相关文档C。除简略报告外,用户还可以查看代码每部分执行了多少次测试等信息(图8.7)。
Coveralls 可以为每一个Pull Request 生成一份报告,我们建议各位使用这项服务,以时常提醒自己注意覆盖率问题。另外,由于用户可以通过详细报告了解哪些代码没有被测试,所以还有助用户改进自动测试的内容,提高测试效率。这项服务对开源开发是免费的,私有仓库则需要支付一定费用。具体金额请查看官方网站。
更多参考
https://coveralls.io/
http://lemurheavy.com/
https://coveralls.io/docs
关于安装和配置自行查找相关资料
Gemnasium
Gemnasium 服务可以查询GitHub 仓库中软件正在使用的RubyGems或npm(Node Package Manager,包管理器),让开发者了解自己是否正在使用最新版本进行开发。
最近的软件都会用到多个库。因此,当库的版本升级时,如果不及时应对,就会影响到软件的使用。比如,帮助用户轻使用GitHub API 的RubyGems 中有octokitA 这样一个库,而我们正在开发的软件正好用到了这个库。现在由于GitHub对API 做了修改,octokit 只好升级版本以做应对。这时RubyGems.org上一定会发布新版本的octokit。如果我们使用了Gemnasium,就会第一时间接到通知。另外,在Gemnasium 的网站上会列出我们正在使用的RubyGems 及其与最新版本的差距。版本方面的问题可以在这里一目了然(图8.11)。

Public 仓库可以免费使用Gemnasium,Private 仓库则需要支付一定费用。如果各位有公开的仓库,推荐试一试这项服务。
Code Climate
Code Climate 是一款代码分析报告服务B,目前只支持Ruby。这项服务可以分析GitHub 仓库中的软件,查出软件中质量有问题的代码,同时给软件品质评级。这是一项收费服务,但是有14 天的免费试用期。Code Climate 可以在我们的日常开发中分析代码,对容易出现BUG的复杂部分发出警告。如果不进行重构,与分析结果相伴的评级就会越来越低(图8.12)。这样一来可以督促我们在日常编写高品质代码,在评级下降时及时进行重构,让软件时常保持在一个高品质状态。
Code Climate 可以帮用户筛选出那些随意敲打出的劣质代码,督促用户时常进行重构。强烈推荐日常使用Ruby 开发的读者尝试这项服务。
Jenkins
概要
Jenkins 是代表性的持续集成服务器,下面我们来讲解如何让Jenkins 与GitHub 集成。
在这里,我们将把GitHub 端仓库发来的Pull Request 设置为触发器,让系统自动进行测试,并将测试结果发送至GitHub。通过这种方法可以检验收到的Pull Request 会不会破坏软件原有功能。另外,如果Pull Request 会给某些功能带来BUG 而无法通过测试,那么这个PullRequest 将会像图8.13 中那样显示在GitHub 上,防止管理员误合并。

通过测试的Pull Request 将会以绿色显示。它表示该Pull Request 至少成功运行了所有测试代码。
测试成功的结果一目了然,让开发者能够放心进行合并。另外,即使没能通过测试,Jenkins 也会持续对该Pull Request 进行测试,让开发者轻松找出发生问题的时间点。
安装
https://www.jenkins.io/doc/book/installing/
Jenkins 的官方网站A 上发布了Linux 等多种OS 下的安装包。各位可以从官方网站的右侧选择合适的安装包进行下载。下载完成后要使用当前OS 的标准安装方法进行安装。Jenkins 在众多环境中都有运行实例,各位大可选择自己悉的环境。当然,需要进行持续集成的目标软件最好在当前环境中可以运行。通过安装包完成安装后,Jenkins 会随OS 一起启动,其他设置也会自动完成。只要安装正常,Jenkins 将会默认使用8080 端口。
各位可以打开浏览器访问“http://jenkins 所在服务器的IP 地址:8080/”,会看到如图8.15 的页面。

至于端口号等JVM 的设置,不同的安装包之间有所不同。使用deb格式的Debian GNU/Linux 或Ubuntu 等Linux 在/etc/default/jenkins 中进行设置,而使用rpm 格式的Red Hat Linux 或CentOS 则在/etc/sysconfig/jenkins 中进行设置。详细位置请参照官方网站的Wiki 。
https://wiki.jenkins-ci.org/display/JENKINS/Native+Packages
创建bot 账户
我们要在GitHub 上新建一个账户,让Jenkins 通过这个账户从仓库获取源代码以及向GitHub 发送测试结果。今后我们将这个账户称为bot账户。
然后要创建bot 账户专用的公开密钥和私有密钥。通过安装包安装Jenkins 时,OS 中会创建一个jenkins 用户,使用这个用户来创建密钥可以自动分配私有密钥,省去后续的麻烦。要注意的是,这个密钥的密码短语(Passphrase)一要留空。由于Jenkins 要通过这个密钥访问GitHub 的仓库,如果设置了密码短语,再想让测试全自动进行可就要费一番功夫了。
接下来将新创建的无密码短语的公开密钥添加到bot 账户中。
账户的创建及设置请参考第3 章。bot 账户的权限设置
我们需要给bot 账户设置GitHub 端持续集成对象所在仓库的访问权限。
公开仓库虽然可以读取,但要将结果添加至GitHub 就必须拥有写入权限。另外,如果对象是非公开仓库,没有读取和写入权限的话bot是无法访问仓库数据的。
对象为个人账户时
如果GitHub 端的仓库归属于个人账户,需要从GitHub 的仓库页面进入Settings 页面,将bot 账户添加到Collaborators 中。添加在这里的账户能够获得这个仓库的写入(push 等)和读取(clone、pull 等)的权限。
对象为Organization 账户时
如果仓库归属于Organization 账户,则需要在GitHub 页面左上角的切换账户处选择Organization 账户。进入Organization 账户页面选择Teams 标签页,打开团队一览(图8.16),然后选择New Team,给bot账户创建一个新的团队。

关于后面的创建团队与权限设置 需要的话可以在看 就不在这里继续copy了
这部分的内容挺多 用的到的话去查看最新资料
小结
通过使用Jenkins 和GitHub pull request builder plugin,我们可以更安全地合并GitHub 的Pull Request。第9 章中我们也会接触到自动测试和持续集成的相关内容。在现代的软件开发中持续集成已经不可或缺,
至逐渐成为开发中的常识。在开源世界中也是同样。在了解一遍过程之后,持续集成的安装会变得很简单。但是在认证和权限设置方面仍存在很多难以处理的东西,往往让人们花费大量时间。因此本书详细讲解了如何让其与GitHub 集成。位不妨参考本书尝试一下持续集成的应用。
第九章 使用GitHub的开发流程
在开发流程中使用GitHub,可以将开发团队的能力发挥到最大限度。下面我们就为各位介绍这类开发流程。
本章中讲解的“开发流程”,是指使用了Git 与GitHub 的团队开发所涉及的规则及步骤。接下来的部分我们将会讲解2 种开发流程,每个流程都有各自不同的特征。在实际开发中究竟要采用哪一种,需要根据现场团队的情况来决定。
对于不熟悉Git 和GitHub 的团队,推荐以本书为参考来制定开发规则及步骤的草案。
团队使用GitHub 时的注意事项
在详细讲解使用Git 与GitHub 的开发流程之前,我们先来看一看由软件开发者们组成的团队要想最大限度地发挥出他们的能力需要具备哪些前提条件。
一切从简
面向企业发售的开发者工具或协作工具往往拥有十分丰富的功能。某些企业为使用这些丰富功能,会专门为其制定软件开发规则。然而不妨反思一下,我们所处的开发现场真的需要这么多功能和规则吗?
GitHub 的各项功能都非常简单,就是因为在实际的软件开发中,往往用不到那些复杂度极高的功能。
项目管理工具与GitHub 的区别
比如图9.1 所示的著名开源项目管理工具Redmine 的新建问题页,从繁多的可输入项目中我们就可以看出其功能的丰富程度。而且Redmine 还有众多插件,可以为其进一步添加功能。然而GitHub 的New Issue 页却如图9.2 所示,非常简单。


为什么会有如此差距呢?
项目管理工具与GitHub 相异的原因
Redmine 等项目管理工具是以管理项目为目的的,势必要考虑管理人员会输入哪些信息,以及需要提醒管理人员输入哪些信息,所以会拥有众多可输入项目
而GitHub 是一款为软件开发者提供支持的工具,与项目管理工具相比,它更注重辅助开发者高速开发高品质软件。要知道,往往事物越是简单,人们实施起来就越快。
在这里,笔者要向准备使用GitHub 的各位开发者提个建议。GitHub本身相较于各位正在使用的项目管理工具确实会有功能方面的不足。但是,先不要急着用其他工具来强行弥补,不妨试着大胆放弃这些功能。
GitHub 的这些简单功能,完全能够应对软件开发中的需要。想让团队最大限度发挥实力,建议剔除复杂规则,只以最简单的规则进行开发。
不Fork 仓库的方法
已经将GitHub 利用到开源软件开发中的读者们想必会以下面的流程进行Pull Request。
❶ 在GitHub 上进行Fork
❷ 将❶的仓库clone 至本地开发环境
❸ 在本地环境中创建特性分支
❹ 对特性分支进行代码修改并进行提交
❺ 将特性分支push 到❶的仓库中
❻ 在GitHub 上对Fork 来源仓库发送Pull Request在无法给不特定的多数人赋予提交权限的公开软件开发中,这种流程能够防止仓库收到计划之外的提交。
然而在公司企业的开发中,开发者每天都要见面,要经常互相发送Pull Request,这种流程就显得有些繁琐了。因此,下面我们要介绍一个不需要Fork 仓库的工作流程。这种方法可以让每一名开发者都掌握着一个本地仓库和一个远程仓库,使整个开发流程变得简单(图9.3)。

GitHub Flow——以部署为中心的开发模式
下面我们为各位讲解GitHub 公司正在实践的一个十分简单的开发流程(图9.4)。

这是一个以部署B 为中心的开发流程。在实际开发中往往1 天之内会实施几十次部署,而支撑这一切的,就是足够简单的开发流程以及完全的自动化。简单的开发流程能够让问题应对变得更加灵活。正在使用GitHub 的各位,请务必尝试这一开发流程。
正因为这一开发流程十分简单,所以无论大小团队都可以取得不错的效果。在GitHub 公司,大致会让15 至20 人组成团队,利用这一流程进行同一项目的开发A。以笔者的经验,由20 人左右的团队使用这个流程来共同开发一个项目,基本不会出现什么大问题。
GitHub Flow 的流程
整个开发流程大致如下。
❶ 令master 分支时常保持可以部署的状态
❷ 进行新的作业时要从master 分支创建新分支,新分支名称要具有
描述性
❸ 在❷新建的本地仓库分支中进行提交
❹ 在GitHub 端仓库创建同名分支,定期push
❺ 需要帮助或反馈时创建Pull Request,以Pull Request 进行交流
❻ 让其他开发者进行审查,确认作业完成后与master 分支合并
❼ 与master 分支合并后立刻部署
以上便是这一流程的全部内容。由于流程中基本只需为特定作业创建特定分支,从开始作业到进行部署之间的过程十分简单,可以降低开发者学习开发流程的成本。而且正由于其简单,所以大量开发者可以迅速将其利用到开发之中,并且可以借助它来灵活处理一些细微的代码变更。
下面我们按顺序一步步进行讲解。
随时部署,没有发布的概念
这个流程必须遵守“令master 分支随时保持可以部署的状态”这一规则。每隔几小时进行一次部署,可以有效防止同时出现多个严重BUG。
虽然有时仍会有一些小BUG 出现,但只要将相应的提交revert 或者提交修正过的代码即可轻松应对。这一流程要以小时甚至分钟为单位持续地进行部署,所以不存在发布的概念。因此,不会出现让HEAD 返回去指向很久之前的提交A,借以取消整个作业内容的情况。
由于master 分支时常保持着可以部署的状态,所以开发者可以随时创建新的分支。
要注意,没有进行过测试或者测试未通过的代码绝不可以合并到master 分支。因此势必要用到持续集成等手段。
进行新的作业时要从master 分支创建新分支
进行新的作业时要从master 分支创建新分支,无论是添加新功能还是修复BUG 都是如此。此外,新分支的名称要具有描述性。所谓具有描述性的名称,是指该名称能直观正确地表达这个分支的
特性,比如以下几种。
● user-content-cache-key
● submodules-init-task
● redis2-transition
其他开发者可以通过这些名字清楚地了解到该分支正在进行什么工作。
采用这一方式,开发者在查看远程仓库的分支列表时,能够对当前团队正在实施的任务一目了然。另外,由于分支名明确描述了工作内容,即便开发者需要先去做其他工作,回来时也能很快想起该分支的工作目标。
查看GitHub 的分支列表页面 还可以轻松掌握各分支与master 分支的差别。
在新创建的分支中进行提交
在前面的步骤中,开发者为了进行新的更改而创建了新分支,并且明确了在这个分支中应该做哪些工作。接下来就可以在这个分支中修改代码,并进行提交了。修改代码时要注意,绝对不能进行与该分支工作内容无关的修改。
在这一阶段,开发者要在提交的力度上多花心思。有意识地减小提交的规模,一方面便于清楚地表达目的,另一方面有助于其他开发者对Pull Request 进行审查。
比如在添加一个方法时,确认添加位置以及类之后,开发者往往还需要进行下面的操作。
● 修正附近代码的缩进问题
● 发现变量单词拼写错误并进行修正
● 添加本次作业中需要添加的方法
如果将上述工作在一次提交中完成,那么一个差别将包含3 种含义,这种提交的粒度就有些不妥。如果将3 个工作分为3 次提交,那么每个差别就有了更清晰的含义。在分支中修改代码与发送提交时只需注意以上几点,其余方面皆可按照往常的方式进行。
定期push
在这一开发流程中,由于除了master 分支之外都是作业中的分支,所以push 作业分支时不需要有太多顾虑。在开发过程中,建议开发者定期将本地仓库中创建的分支以同名形式push 到GitHub 端的远程仓库。
这样一来不仅可以备份代码,还会定期给开发者团队创造交流的机会。其他开发者在做什么工作,是否需要帮助等,团队成员可以通过GitHub 的分支列表页面一目了然。
在开发过程中,最好让其他开发者能够看到自己编写的代码,同时养成积极查看其他人代码的习惯。通过代码进行交流是开发者的特权,我们没有理由不去利用。
使用Pull Request
Pull Request 不一定非要在与master 分支合并时才使用。既然是团队开发,完全可以尽早创建Pull Request 让其他开发者进行审查,一边听取反馈一边编写代码,没必要等到与master 分支合并时再进行。Pull Request 具有显示差别以及对单行代码插入评论的功能,开发者可以利用这些进行交流。另外,如果希望得到特定开发者的反馈或建议,可以在评论中加入“@ 用户名”,给该用户发送Notifications。对方注意到之后,照例都会以某种形式进行反馈。
务必让其他开发者进行审查
一个分支的作业结束后,需要注明作业已完成,让其他开发者进行审查。找其他开发者看一看自己编写的代码,可以有效防止想当然的错误或者低级失误。审查时要选择没有参与编写的人,被指出有问题时,要积极进行修改。当然,这一切的大前提是该部分代码已经通过所有自动测试。
审查之后如果认为可以与master 分支合并,则需要明确地告知对方。按照GitHub 的文化,这里会用到“:+1:”或“:shipit:”等表情(图9.5)。偶尔也会见到LGTM 的字样,这是Looks good to me 的简写。征得多个人同意后,便可找个适当的时机让其他开发者将该分支与master 分支进行合并。

实践GitHub Flow 的前提条件
至此,相信各位已经对这一开发流程有了大体印象。接下来我们需要考虑实践这一开发流程所需的前提条件。
部署作业完全自动化
首先,部署的相关作业必须实现自动化。传统按部署文档进行部署 会浪费很多时间.
使用部署工具
于是,我们要使用Capistrano 等部署工具,让部署时所需的一系列流程自动化。一旦实现自动化,部署工作就能够简化成一条指令,同时大幅减少粗心大意导致的人为失误,让所有参与开发的人都能够放心地实施部署工作。
另外,这类部署工具都有回滚功能。不小心部署了有问题的代码时,只需一条指令就可以将版本回滚至部署之前。为此,最好让所有参与开发的人都能进行回滚操作。
显而易见,只需将以往用来编写操作顺序手册和进行维护的时间拿出一点来编写部署工具的代码,就可以换来众多好处。
通过Web 界面进行部署的工具
Capistrano 等部署工具需要使用命令行执行操作,开发者以外的人很难实施部署。而Webistrano 和Strano 等工具则提供了通过Web 执行部署指令的界面,能够帮助团队成员解决这个问题。一个团队除了开发者以外,往往包含美工或HTML 编辑等人,在开发过程中,创建一个让团队所有相关人员都能放心部署的环境至关重要。表9.1中列出了几种具有代表性的部署工具。

导入开发时的注意事项
随着团队人数增多以及成熟度提高,开发速度会越来越快。这时往往一个部署尚未完成,另一名开发者就已经处理完下一个Pull Request,开始实施下一个部署了。在这种情况下,一旦正式环境中出现问题,很难分辨是哪个部署造成的影响。为了应对这种情况,建议在部署实施过程中通过工具上锁,或者在实施部署时通知整个团队等,通过严格贯彻这类规则来消除隐患。
重视测试
让测试自动化
如果每次部署到正式环境前都需要在测试环境中手动进行测试,那这一开发流程也就无从谈起了。所以必须让测试自动化,令其自动检测是否有代码被意外破坏,以及是否出现BUG。
编写测试代码,通过全部测试
每一名开发者都必须编写测试代码。成品代码的Pull Request 中如果不包含测试代码,是不可以合并至master 分支中的。只有包含测试代码并且通过了所有测试的成品代码才可以被合并至master 分支。
开发者确认代码在本地环境中通过了所有测试后,将其push 到远程仓库。随后Jenkins 或Travis CI 等CI 工具会自动对其进行测试,测试结果由CI 工具第一时间通知开发者。经过这一流程,系统能够自动检测出软件是否遭到破坏。我们在8.6 节中已经详细讲解过如何构建与GitHub 集成的Jenkins 环境,各位可加以参考。
维护测试代码
要注意的是,测试代码必须时常进行维护,以保证能够在开发流程可承受的速度范围内完成所有测试。顺便一提,GitHub 公司可以在200秒内实施14 000 个自动测试 。这么短的时间内完成如此多的测试项目,效率实在惊人。
这一工作流程以部署为中心,通过简单的功能和规则,持续且高速安全地进行部署。至此相信各位都已经有了一定程度的理解。不论是添加新功能还是修正小BUG,全都通过同一流程进行。它的高效正源于它的简单。从结果上看,简单的构造让这一开发流程兼具了高速度与灵活性。各位不妨也让自己的团队试着采用这一开发流程。
模拟体验GitHub Flow
通过前面的讲解,各位对开发者实施GitHub Flow 的步骤应该有了一个具体的了解。现在就让我们一起来结合GitHub 上的交流体验这一流程。现在假设各位是负责给某软件开发功能的开发者,并且所在团队正在实践GitHub Flow。账户名为ituring,仓库名为fizzbuzz。我们即将讲解的软件已经公开了代码,请各位将其仓库Fork 至自己的GitHub 账户下,与我们一起动手尝试。下面我们将“Fizzbuzz 问题” 作为编程的题材。
Fizzbuzz 的说明
假设我们的团队已经开发了一款名叫Fizzbuzz 的软件。
这一软件在输出1 至100 的数字时会如下显示。
● 3 的倍数时显示fizz
● 5 的倍数时显示buzz
● 3 与 5 的公倍数时显示fizzbuzz
● 除上述情况外直接显示数字
就是这样一个简单的软件。
现在就来讲解我们作为这个软件开发团队的一员,实践GitHubFlow 时的情景。
添加新功能
现在我们被分配了新工作,那就是添加下面这个新功能。
● 含有7 的数字时显示GitHub
看起来应该很简单,我们这就动手吧。
创建新的分支
在GitHub Flow 中,无论是实现新功能还是修正BUG,都需要从能正常运行的最新master 分支中新建一个分支。所有实际修改都在这个新建的分支中进行。
如果尚未clone 仓库
首先需要Fork 已经公开的仓库 。如果尚未获取仓库,则需要使用下面的命令进行clone。各位请将仓库路径替换为自己的对应路径。
$ git clone git@github.com:ituring/fizzbuzz.git
Cloning into 'fizzbuzz'...
remote: Counting objects: 18, done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 18 (delta 2), reused 17 (delta 1)
Receiving objects: 100% (18/18), done.
Resolving deltas: 100% (2/2), done.
$ cd fizzbuzz在fizzbuzz 目录下新建了一个仓库,这个仓库与远程仓库拥有相同状态。
如果之前clone 过仓库
假设本地已经有之前clone 来的仓库,现在正在开发途中并不需要重新clone,那么我们应该将master 分支更新成远程仓库最新master 分支的状态。流程很简单,只需切换到本地仓库的master 分支,然后将远程仓库的master 分支pull 到本地即可。
$ git checkout master
Switched to branch 'master'
$ git pull
First, rewinding head to replay your work on top of it...
Fast-forwarded master to 51412d2d518af30deaa8fd5e6469c9376ee1f447.通过以上操作,我们手头就有了最新状态的master 分支。
创建特性分支
现在我们已经完成了从master 分支创建新分支的所有准备工作。我们将新分支的名字定为7-case-output-github。
在master 分支中使用下述命令创建新分支,并切换到新分支。$ git checkout -b 7-case-output-github
Switched to a new branch '7-case-output-github'为方便团队其他人通过分支名称知道我们在做什么,我们在GitHub端的远程仓库中创建一个同名分支。
$ git push -u origin 7-case-output-github
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:ituring/fizzbuzz.git
* [new branch] 7-case-output-github -> 7-case-output-github
Branch 7-case-output-github set up to track remote branch 7-case-output
-github from origin. 创建分支大概就是这个步骤。今后我们可以每当工作告一段落时,定期将这个特性分支push 到远程仓库。
实现新功能
现在我们来实现新功能——含有数字7 时显示GitHub。原本的代码(fizzbuzz.rb)如下,
class Fizzbuzz |
现在我们添加含有数字7 时的代码,diff 如下。
@@ -6,6 +6,8 @@ class Fizzbuzz |
我们试着执行一下,结果运行正常。
$ ruby exec.rb |
提交本次实现的内容。
$ git commit -am "Add output GitHub" |
新功能已经顺利实现,现在将其push 到远程仓库。
$ git push |
GitHub 端远程仓库中的分支应该已经被更新。我们打开GitHub 的分支列表页面,能看到该远程分支与master 分支的差别(图9.6)。点击之后可以查看差别的详细内容。

创建Pull Request
至此,我们已经顺利实现了新功能,接下来就是从7-case-outputgithub分支创建一个Pull Request 发送给master 分支,请求与master 合并(图9.7) 。创建Pull Request 的相关操作请参照第6 章。

在Pull Request 中写明希望得到审查。如果想让特定的人来进行审查,可以在评论中加入“@用户名”,这样该用户就会收到Notifications。现在我们已经创建并发送了Pull Request,只需等待其他开发者的反馈即可。
接收反馈
距离发送Pull Request 已经过了几个小时,我们再次登录GitHub。此时已有其他开发者已经发来了反馈(图9.8)。
对方为我们指出了2 个问题。
● 缩进不正常
● 没有测试代码
点击“缩进好像不太对”所指的链接,我们可以看到如图9.9 所示的页面,其中清楚地显示出评论所指代码的位置。确实与前面elsif 的缩进没有对齐。


至于测试代码,我们确实在添加新功能时没有添加相应的测试代码,对方指出的问题确实存在。接下来,我们要着手处理这2 个问题。
修正缩进
下面,我们来修正对方指出的代码缩进问题。修正后的diff 如下所示。
@@ -6,7 +6,7 @@ class Fizzbuzz |
然后将修改提交至本地的7-case-output-github 分支。
$ git commit -am "Fix indent" |
接下来将该分支push 到GitHub 端的远程仓库,为远程仓库分支添加这项修改。
$ git push |
这时我们再打开GitHub 查看Pull Request,会发现这个用于修正的提交已经添加至Pull Request(图9.10)。

添加测试
在GitHub Flow 中,不可以将没有测试代码的成品代码加入master分支。因此我们被其他开发者指出没有编写测试代码了。
一般来说应该是下面这样的顺序。
● 将 master分支更新到最新状态
● 在自己的开发环境中确认通过所有测试
● 从 master分支创建新分支
● 编写测试代码
● 编写实现目标功能的代码
● 确认通过所有测试并且没有出现退步(Regression)现象
● 发送 Pull Request请求合并至 master分支
也就是应该先编写目标功能的测试代码,以保证测试代码全部通过为基准编写功能代码。这个操作顺序能够极力减少出现BUG 的可能,并且可以随时修改功能代码。由于本次我们直接编写了功能的功能代码,所以需要回过头来再为其添加一份测试代码。
根据已有的测试代码为本次实现的功能编写测试代码时,我们突然有了一个疑问。
例如75 这个数字,它既是3 的倍数也是5 的倍数,按照旧功能会显示为fizzbuzz,那么在添加新功能后它应该显示为GitHub 吗?还是说应该显示成fizzbuzzGitHub 这种组合形式呢?关于这种情况我们并没有接到说明,所以保险起见,我们通过Pull Request 确认一下。
在Pull Request 中写下如图9.11 所示的评论。
不久,我们收到了其他开发者的反馈(图9.12)。
按照反馈的指示,我们在fizzbuzz_spec.rb 中添加测试代码。


context 'GitHub number' do |
我们添加了具有以下意图的测试。
● 17 与77 中包含7,所以显示GitHub
● 27 虽然是3 的倍数,但仍然显示GitHub
● 75 既是3 的倍数也是5 的倍数,但仍然显示GitHub
然后执行测试。
$ rspec |
从上面我们可以看到,27 与75 时并没有显示GitHub,因此代码需
要进行修正。修正后的差别如下。
@@ -1,13 +1,13 @@ |
我们将判定是否显示GitHub 的语句换了个位置。这段代码理所当然地通过了所有测试。
$ rspec |
至此,我们添加了测试代码,成品代码也能按照预期顺利执行了。
培育Pull Request
为了将我们编写的新功能合并到master 分支中,要进行提交并push。
$ git commit -am "Fix output GitHub" |
确认Pull Request 没有问题之后,便可以通过评论请求与master 合并了(图9.13)。
这一系列反馈与代码更新的过程,我们称作培育Pull Request。

Pull Request 被合并
随后,我们的代码通过了其他开发者的审查,被顺利合并至master分支(图9.14)。

合并完成后,这个master 分支将被立刻部署至正式环境 。
通过创建Pull Request 获取反馈并逐渐培育Pull Request 的过程想必各位已经有了初步的了解。在实际开发现场,会有更多开发者共同参与到这个交流过程中。
习惯了在Pull Request 上进行交流后,我们将能更精确地表达出代码的意图,审查的效率也会越来越快。熟练运用Pull Request 是这一开发流程成功的关键。
希望各位能将这一开发流程应用到自己的开发现场,以便更加灵活地使用GitHub。
tips 这一系列交流可以在GitHub 上阅览。https://github.com/ituring/fizzbuzz/pull/1
团队实践GitHub Flow 时的几点建议
至此,相信各位已经清楚GitHub Flow 需要以什么样的流程来实施。但是在开发现场实际采用这一流程时,还会遇到一些令人苦恼的问题。在这里,笔者将从自身经验出发,为各位介绍几个成功运用这一开发流程的窍门。
减小Pull Request 的体积
很多团队在开发时,喜欢将一个功能放到一个分支中进行开发。这里各位不妨思考一下,这一个功能是不是还能继续细分?
比方说接下来的一个新功能我们预计要花2 周来实现。试想一下,大约2 周时间编写出来的代码,即便最后顺利进入Pull Request 阶段,这个代码量也会给代码审查方带来非常重的负担。
开发时间越长或者代码量越大,代码审查时的成本就越高。过长的开发时间让审查者难以了解开发该功能时的背景,过大的代码量会让审查者难以阅读到代码的每个细节。这样一来BUG 更容易出现,久而久之整个团队的代码审查都会漏洞频出。
在这种团队状态及环境下,要把经过漫长时间编写出来的代码突然部署到正式环境中,将会是一个让人畏手畏脚的高风险工作。其结果便是导致整个开发速度减缓。
与开发了2 周的分支相比,只开发了1 周的分支的代码量更少,审查者在理解代码时的成本也更小,相对而言能更快合入master 分支。以此类推,花3 天时间开发出的代码会怎样?花1 天时间开发出的代码又会怎样?相信各位可以想象得出。
在刚刚采用这一开发流程,对整个流程还不是很习惯时,建议各位将目标功能细分,尽量缩小Pull Request 的体积,保证每几小时至几天向master 分支发送一次Pull Request,通过多次合并来实现一个功能。这样一来不但能有一个很好的开发节奏,软件的成长过程也能够更加安全可靠。
所以各位在创建新的分支之前,不妨先对目标功能或内容进行讨论,看看是否能分割成几个更小的Pull Request。
准备可供试运行的环境
不管我们写了多少测试代码,只要该分支中包含了对软件关键部分的修改,在将其部署到正式环境时都需要极大的勇气,而且这时还伴随着很高的风险。
于是,我们不妨创建一个与正式环境高度相似的预演(Staging)环境,在这个预演环境中部署关键修改,借以确认代码的实际运行状况。当然,向预演环境的部署也需要实现自动化。
如果分支中包含“对数据库进行了大幅修改”“实施了大规模重构”“对充值处理部分进行了大幅修改”这类对系统有重大影响的关键性修改,为安全起见最好先将其部署到预演环境中进行试运行。但要注意,不要把所有修改都拿到预演环境中进行试运行,免得画蛇添足。
近来的Web 应用程序往往会先对部分用户(通常是1%)进行部署,通过Twitter 等SNS 监控是否出现了重大影响。
如果出于不安总想把部署向后搁置,不如准备一个环境来消除不安,让代码可以迅速部署到正式环境中。
不要让Pull Request 中有太多反馈
笔者在接到Pull Request 时遇到过下面这种情况:代码存在多处问题,进行多次指正和修改后仍然无法达到与master 分支合并的水准。出现这种情况大概有两个原因。
一是交流不足。如果创建Pull Request 的理由没有获得认同,那就不要通过Pull Request 进行讨论,而是应该选择其他手段进行交流。最好的解决途径是直接面谈。
另一个原因是技术或能力不足。如果代码经常被指出问题,那么不是编程能力方面有问题,就是团队编写代码时没有一个明确的规则。为避免在无用的讨论上浪费时间,团队应该制定一个最低限度的编程规则,并且告知每一名团队成员。如果在开发过程中还需要其他规则,可以将这些规则整合到Wiki 中,便于阅览及修改。
如果在类的设计、方法的实现、变量的命名等方面频繁出现问题,不妨实施一些能提高开发者编码技术的措施,效果要远好于一遍遍反复指正。
● 结对编程
● 组织学习小组共享知识
● 共享可供参考的资料
不知各位的团队中是否实施了这些措施。在这些措施之中,结对编程收效最佳。
GitHub Flow 是以部署为中心的开发流程,所以要求团队中每一名开发者都能编写出高品质的代码,以便顺利通过审查,迅速完成从合并到部署的过程。因此需要锻炼开发者,保证每一名团队成员都能达到这一水平。
不要积攒Pull Request
在以部署为中心的开发流程中,如果总有大量Pull Request 处于等待审查或等待修正的状态,会导致长期无法部署,引发严重问题。
如果每一名开发者都在忙于实现各自的新功能,把所有精力都放在编写代码和创建Pull Request 上,势必会忽视审查与反馈工作。时间一长,无法部署的Pull Request 就会堆积如山。
为防止这一情况发生,建议团队制定一个新的规则:想创建PullRequest 的人要先去对其他人的Pull Request 进行审查及反馈,并在可以部署时及时部署。
这样一来,自己想创建Pull Request 时必须先处理其他人的PullRequest,就可以有效避免Pull Request 堆积的情况发生。
GitHub Flow 的小结
笔者根据自身经验,提出了一些开发现场容易出现的问题。各位在开发的过程中必然还会遇到其他恼人的问题。对于这些问题,请遵循以下这两点去寻找解决方案。
开发流程以部署为中心
高速源于简单
只要不偏离这两点,各位一定能找到适合自己开发现场的解决方案。
Git Flow——以发布为中心的开发模式
荷兰程序员Vincent Driessen 曾发表了一篇博客A,让一个分支策略广为人知,那就是A successful Git branching model。这里我们将向各位介绍一个以它为基础,组合了GitHub 的开发流程。
在这个开发流程中,每个分支都显示出代码的当前状态。流程中设置了负责管理软件发布Release 的发布管理员,适用于以发布为中心的软件开发。
过整体的流程图(图9.15),我们不难看出该流程分支间的代码流向十分复杂。关于每部分的详细内容我们将在稍后进行讲解。
便于理解的标准流程
从软件开发者的角度观察这一开发流程时会发现,该流程用分支名表示标准软件开发中开发状态的迁移。
❶ 从开发版的分支(develop)创建工作分支(feature branches),进行功能的实现或修正
❷ 工作分支(feature branches)的修改结束后,与开发版的分支(develop)进行合并
❸ 重复上述❶和❷,不断实现功能直至可以发布
❹ 创建用于发布的分支(release branches),处理发布的各项工作
❺ 发布工作完成后与master 分支合并,打上版本标签(Tag)进行发布
❻ 如果发布的软件出现BUG,以打了标签的版本为基础进行修正(hotfixes)

整个流程看上去应该比较好理解。这一流程最大的亮点在于考虑了紧急的BUG 应对措施。
有时显得过于复杂
这个开发流程的问题在于需要记忆的分支状态很多,在实施之前必须对整个开发流程进行系统地学习。虽然团队成员可以通过我们即将讲到的git-flowA 等工具得到辅助,但很多情况下,流程整体对于我们的实际开发现场来说仍然显得过于复杂。
在这个流程中,程序员必须理解自己正在进行的修改会对哪些分支产生影响。一个分支的工作结束后,有时需要与多个目标分支合并。这些是该流程中最为复杂的部分,需要团队谨慎处理。同时由于其复杂程度高,容易出现操作失误等人为错误。所以团队需要使用git-flow 等工具进行辅助,时刻保证开发不偏离流程。
考虑到上述种种因素,各位的团队在采用这一开发流程之前必须进行系统学习,充分掌握其优势与劣势。下面,我们先为该流程的辅助工具构筑环境,再通过Git 与GitHub 的操作向各位进行详细讲解。
导入Git Flow 前的准备
安装git-flow
现在我们要安装git-flow,各位请根据自己当前的环境进行安装。git-flow 是一款辅助Git Flow 的工具,虽然不安装它也可以实施该开发流程,但那样一来所有工作都必须手动完成。为防止出现人为失误,这里还是建议各位安装这个工具。
不过多赘述 以最新资料为标准
参考:
https://github.com/nvie/gitflow
https://jeffkreeftmeijer.com/git-flow/
https://nvie.com/posts/a-successful-git-branching-model/
模拟体验Git Flow
不过多赘述 以最新资料为标准
参考:
https://github.com/nvie/gitflow
https://jeffkreeftmeijer.com/git-flow/
https://nvie.com/posts/a-successful-git-branching-model/
Git Flow 的小结
这一开发流程在软件开发世界中存在已久,并没有什么太新颖的地方。但也正因如此,它更容易为软件开发者所理解。
但是,由于在实际开发现场需要多人分工合作,这一开发流程往往会变得很复杂。建议各位把开发流程图 放大并张贴在墙壁上,这样能够有效帮助团队成员理解流程内容。

第十章 将GitHub应用到企业
本章中,我们将对企业等工作场所引入GitHub 时的相关问题进行探讨。程序员应该将资源集中于编写优秀的软件上,GitHub 则是辅助这一过程的工具。因此,当今的软件开发企业理应积极引入GitHub。本章将为各位讲解一些有用的信息,帮助各位在企业引入GitHub。
将世界标准的开发环境引入企业现场
笔者认为,GitHub 已经称得上一种世界标准的开发环境。至少在开源世界,几乎所有的开源项目都在GitHub 上公开过源代码。另外,已经有相当多的企业开始使用OSS。
相信在各位读者之中,相当一部分人都与开源世界有着不可分割的关联。
企业引入GitHub 的好处
打个比方,很多程序员在业余时间经常使用GitHub,如果将GitHub 引入公司,这些人就可以按照自己习惯的方式进行开发,不会产生多余的压力。同样,让新入行的程序员在企业中使用GitHub,能使他们很快接触到开源开发世界,促使他们对GitHub 上的众多软件项目产生兴趣。
软件行业人才流动性很强,一般情况下,程序员半途加入项目需要先熟悉企业内部软件、项目以及代码的相关信息,从加入到发挥作用往往需要2 ~ 4 周时间。
然而,由于相当多程序员都在使用GitHub,所以上述情况如果放在应用了GitHub 的企业,很可能新员工进公司第一天就能开始编写代码并发送Pull Request 了。要知道,GitHub 在全世界已经相当普及。
另外,GitHub 还能省去维护内部仓库服务器的成本,让程序员们能全神贯注地开发软件。
使用Organization
企业应用GitHub 时建议使用Organization 账户。利用这一功能,可以让开发者们使用同一控制面板,还能够创建团队并统一管理权限。另外这一账户还为企业提供了用户管理和支付等便捷功能。费用与个人账户不同。具体情况请参考GitHub 的Organization Plans。
确认Github 的安全性
由于源代码相当于企业的财产,在企业中导入GitHub 时势必会对信息安全体制有所顾虑。其实GitHub 公司已经在网络上发布了安全保障的相关信息。
用户的数据不仅被严密保管在GitHub 公司的数据中心,该公司还给客服人员制定了严格的操作规范及相关权限。详细内容请查阅官方网站。
注意维护时间
GitHub 在一年内会有几次短时间的系统维护,国内的企业在这一点上需要加以注意。
GitHub 的维护时间选在美国的深夜,因为时差的关系国内会是白天。也就是说,那几天我们可能会在工作时间中无法访问GitHub。
GitHub 方会在维护前发布系统广播,而且Git 是分散型版本管理系统,服务器维护并不会导致项目开发彻底停滞。只是为了防止意外情况的发生,最好留意一下服务器维护的日期。
GitHub 的大规模系统维护公告发布在官方博客的Broadcasts 上。
如图10.1 所示,个人控制面板的右上方也会显示这个Broadcasts。如果各位每天都使用GitHub,那么基本不用担心漏看这一信息。
现在可以关注Github Status

查看故障信息
GitHub 在官网上公开了故障信息(图10.2)。如果把一些细微故障算进去,GitHub 发生故障的频率还是相当高的。但是各位从故障信息记录中不难发现,其对故障的反应及处理也十分迅速。

如果各位正在开发的软件需要在规定时间发布,建议事先构建一个GitHub 之外的备用发布方案,以便在GitHub 故障时能保证按时发布。
另外,GitHub 还在官网上以图表形式公开了特定时间段内各项服务的性能及正常运行率等信息(图10.3)A。各位在使用服务时可以拿来做参考。

GitHub Enterprise
GitHub 公司为需要内部部署GitHub 的企业准备了GitHub Enterprise(GHE)B。近年来,GitHub Enterprise 已被许多大型IT 企业所采用。
此处内容 讲了 GitHub Enterprise 的概述
- 引入的好处
- 引入的弊端
- 适合引入GitHub Enterprise 的几种情况
- 源代码不可外传
- 希望维护与故障时间可控
仅把标题拿过来了 具体内容可以去看书 不过多展开
能实现Git 托管的软件
有一些开源软件拥有与GitHub 相类似的功能。
例如下面几种都比较常用。
● GitBucketA
● GitLabB
● GitoriousC
● RhodeCodeD
如果想免费创建与GitHub 类似的协作开发环境,那么选择上述类型的软件不失为一个好办法。不过,这些软件虽然提供了与GitHub 类似的功能,但毕竟不是GitHub 本身,所以在使用之前要先确认其是否
包含自己需要的功能。
这类软件都有自己的UI,所以在熟悉操作时需要花费一些学习成本。另外,在运用方面虽然省去了购买的开销,但软件终究无法提供GitHub 的所有便捷服务,导致开发者在开发过程中需要时常注意其与GitHub 的不同之处。因此,如果要追求效率,还是建议选择GitHub。
tips: Bitbucket
Bitbucket 是Atlassian 公司提供的一项服务,它所提供的功能与GitHub 几乎完全相同。接触过GitHub 的用户在使用
Bitbucket 时不必学习新的概念,但由于UI 上的区别,所以需要一个习惯的过程。
当初该服务主要为分散型版本管理系统Mercurial 提供仓库托管服务,目前已经开始支持Git。
该服务对每个账户的仓库数量及单个仓库的容量都没有限制,而且公开与私有仓库都可以免费创建。
可随意创建私有仓库这点确实很吸引人,但非公开仓库的可访问用户数需要付费购买。免费的情况下只允许5 名用户拥有访问权限,多人共用一个仓库时势必需要支付一定费用。这方面详细信息请参考官方网站。
如果源代码仅供个人或有限几人使用,那么Bitbucket 要比GitHub 更能节省开支。
小结
本章就企业导入GitHub 时需要了解及考虑的问题进行了讲解。GitHub 给OSS 世界的软件开发带来了变革,同样,它也一定能为各位所在企业的软件开发带来新的理念。以软件开发为主的企业不妨积极导入GitHub,加以尝试。
附录A :支持GitHub的GUI客户端
在企业中引入GitHub 后,势必会有一些人不习惯CLI 的操作。下面我们为这些读者介绍几款简单易用的Git 的GUI 客户端。相较于不常接触的CLI 而言,GUI 客户端更容易入门。但要想做到运用自如,必须先理解Git 的clone、push、pull、合并等基本概念。建议各位读者在阅读本书的同时,尽量实际动手操作GUI 客户端,以便加深记忆。
A.1 GitHub for Mac,GitHub for Windows
GitHub 公司提供了Git 客户端来辅助用户使用GitHub。该客户端有Mac 版(图A.1)A 和Windows 版(图A.2)B 两个版本。两个客户端提供的功能基本相同,只是由于OS 不同,所以UI 有些许差异。
A.2 SourceTree
Atlassian 公司为用户提供了一款名为SourceTree(图A.3)A 的应用程序。这一应用程序同时支持Git 与Mercurial,并且可以与Atlassian 公司提供的Bitbucket 以及内部部署中使用的StashB 进行集成。
附录B:通过Gist轻松实现代码共享
Gist 是一款简单的Web 应用程序,常被开发者们用来共享示例代码和错误信息。开发者在线交流时难免会涉及软件日志的内容,但直接发送日志会占据很大的篇幅,给交流带来不便。这种情况下,笔者习惯把日志粘贴到Gist,然后将URL 发送给对方。
此外,Gist 还可以用在如下场合。
替记事本记录简短代码段
给对方发送示例代码
使用Gist 处理这类情况可以省去不少麻烦。
B.1 Gist 的特点
Gist 最大的特点是可以与其他人轻松分享示例代码。它使用JavaScript 编写的AceB 编辑器,只需打开浏览器便可编写简单代码。
另外,Gist 中的文档都在版本管理系统的管理之下,用户可以放心编辑。而且由于其版本历史记录保管在Git 仓库中,所以还可以通过clone 操作将Gist 获取至本地。共享Gist 的人之间能够互相添加评论,所有交流都会被记录下来。
Gist 支持多种语言的语法高亮,可以大幅增强代码可读性。可以说,这一工具就是专为程序员设计的。
B.2 创建Gist
下面我们通过实际演示为各位讲解Gist。各位可以登录GitHub 后点击上部菜单中的Gist 或者直接访问Gist 的URL。随后我们可以看到如图B.1 中所示的页面。

UI 讲解
接下来我们就各个项目分别进行讲解。
1 Gist description
头像右侧的这个文本框用来对当前Gist 所包含的文件进行简要的说明。说明内容应尽量简明扼要,让自己一看就知道是什么。当然,阅览者也能看到这里的信息。此项目并不是必填项,所以如果内容没有值得说明的地方,这一项大可不必填写。
2 name this file
这一项可供用户指定文件名。系统能够自动识别扩展名,将右侧的语言自动设置为对应种类。比如我们输入“hello_gist.rb”,语言会自动设置为Ruby。
此项目不是必填项,缺省状态下会以“gistfile1. 扩展名”的形式自动分配名称。
3 language
这里可以给要创建的文件选择编程语言。如果前面没有指定文件名,那么缺省名称的扩展名将以这个设置为准。另外,文件中的代码会按照这里设置的语言进行语法高亮。下拉菜单中可以搜索语言(图B.2),各位请选择适当的语言进行设置以提高可读性。如果不更改设置,则文件默认为文本格式。


下面还可以创建公开gist

点击添加文件可以在一个gist创建多个文件

小结
本部分中我们对Gist 进行了讲解。通过这款应用,我们可以轻松共享笔记、错误信息以及一些没必要放入仓库的代码片段。各位不妨在日常中多加利用,与其他人共享琐碎信息。
完结撒花 !!!
三天看完啦 以后用到github工作流 需要的话 在回看一遍! 告辞!
2022/4/11 17:18
.jpg)
.jpg)




