Pull Request

向开源项目提出你的合并

  • Fork

fork 你想 PR 的项目到自己的仓库。

  • clone

把 fork 的项目 clone 到本地。

  • branch

创建一个 work 特征的特征分支,并切换到该分支下。

  • 添加代码提交修改

提交到对应的特征分支下,没有的话自己在 GitHub 新建一个远程分支

  • 发送你的 pull request

根据要合并项目的 issues 要求规范填写你的合并缘由,等待管理员的处理

开发中的 Pull Request

对可能实现的功能或更改进行讨论,可以使用 TaskList ,这样可以清晰的了解到哪些功能没有实现,哪些功能已经实现增加审查者的效率,也可以做为备忘录使用。

接收 Pull Request

  • 代码检查

将接收的内容放在本地,使用集成测试进行检查,检验代码是否能运行和安全,是否符合规范和要求。

在本地检查需要合并的内容

  • 将接收的本地仓库更新到最新
  • 获取附送方的远程仓库
  • 创建用于检查的分支
  • 合并

将通过检查的检查分支代码与提交者的特征分支进行合并

  • 删除分支

删除用于检查的分支

确认安全的合并

如果以上代码检查没有问题就可以在 Pull Request 页面点击 Merge pull request,进行合并。
这个合并过程是一个自动的过程,如果代码比较少,可以直接在 GitHub 网站的网站对比直接进行合并。

GitHub Flow 的开发流程

开发流程

  • 令 master 分支处于随时可部署的状态
  • 进行新的作业时要从 master 分支创建新的分支,新分支名称要具有描述性
  • 在创建的本地分支进行提交
  • 在 GitHub 端创建同名分支,定时 push
  • 需要帮助或者反馈时创建 Pull Request ,以 Pull Request 进行交流
  • 让其它开发者进行审核,确认作业完成后与 master 分支合并
  • 与 master 分支合并后立即部署

具体介绍

  • 实时部署,没有发布的概念
  • 进行新的作业时要从 master 分支新建新的分支
  • 在新创建分支中进行提交

提交粒度小,一旦完成小的任务,就提交

  • 定期 push

备份代码。定时交流

  • 使用 Pull Request

不是在最后 master 合并时才 PR,而是写完一部分功能后就 PR ,这样可以一边编码,一边听取他人的修改意见

  • 务必让其他开发者进行审查

审查时找没有参与作业的,而且代码应该通过自己的测试

  • 合并后立即部署

确认合并后的代码是否存在问题

实践GitHub Flow 的前提

部署作业完全自动化

  • 使用部署工具
  • 通过 Web 界面进行部署的工具
  • 实施部署时的锁

重视测试

  • 让测试自动化
  • 编写测试代码,通过全部测试
  • 维护测试代码

Git Flow 的开发流程

以发布为中心的开发模式

标准工作流

  1. 从开发分支创建工作分支,进行功能的实现或修正
  2. 工作分支结束后与开发分支进行合并
  3. 重复 ① ② 直至功能可以发布
  4. 创建用于发布的分支,处理发布的各项工作
  5. 发布工作完成后与 master 分支合并,打上版本标签进行发布
  6. 如果发布的软件出现 BUG ,以打了标签的版本为基础进行修正

导入 Git Flow 的准备

  • 安装 git-flow
  • 仓库初始化
  • 创建仓库
  • 进行 git-flow 的初始化
  • 在远程仓库也创建 develop 分支

Git Flow 工作流

git-model@2x.png

master 分支与 develop 分支的区别

master 分支始终保持可发布的稳定状态,发布时必须包含版本标签。这个分支不允许开发者直接修改和提交。develop 分支是开发过程中的代码中心,这个分支和 master 分支一样不允许开发者直接修改和提交。程序员需要自己新建 feature 分支,在 feature 分支中开发和修正。也就是说,develop 分支维持着开发过程中的最新源代码。

在 feature 分支中的工作

  1. 从 develop 分支创建 feature 分支
  2. 在 feature 分支中实现目标功能
  3. 通过 GitHub 向 develop 分支发送 Pull Request
  4. 接收其他开发者审核后,将Pull Request 合并到 develop 分支

完成的 feature 适当时间进行删除

通过代码审查实现代码质量的提升

  1. 由其他开发者进行代码审查,反馈在 Pull Request 中
  2. 修正代码反馈的内容
  3. 将修改后特征分支推送到远端(自动添加到之前的 Pull Request)
  4. 重复前三步
  5. 确认 Pull Request 没有问题,合并到 develop 分支

反馈的几个要点:

  • 没有测试or未通过测试
  • 违反编码原则
  • 代码品质过低(命名不明确, 方法冗长)
  • 还有重构的余地
  • 有重复的部分

在 release 分支的工作

  • 创建分支

以最新的 develop 分支创建一个发布分支

  • 分支内的工作

只处理与发布前有关的提交,如:版本编号变更、bug 的修正。该分支不能包含功能的添加、变更等内容

  • 进行发布与合并

合并至 master 将项目发布

  • 查看版本标签
  1. $ git tag

在 hotfix 分支中的工作

  • 创建新的补丁分支
  • 进行版本修复
  • Pull Request
  • 创建标签并发布
  • 最后将它合并到开发分支

版本号的分配规则

格式: x.y.z

  • x 在重大内容更新或不向下兼容时加 1,此时 y、z 归 0
  • y 在添加或删除新功能加 1,此时 z 归 0
  • z 只有在内部修改时加 1

举个例子:

  • 1.0.0:最初发布的版本
  • 1.0.1:修复了轻微的 BUG
  • 1.0.2:修复了漏洞
  • 1.1.0:添加了新功能
  • 2.0.0:更新整个 UI 并添加新功能

可以采用 Linux 操作系统对版本号的命名规则:版本号第二位如果是奇数,则为非稳定版,如果为偶数则为稳定版。当奇数版本就是下一个稳定版本的开发版本,例如 2.9 就是下一个版本 3.0 版本的开发版本。

注意事项

  • 在合并后更新本地 develop 分支
  • 将 develop 分支设为默认分支,省去手动切换分支的麻烦

GitFlow 例子

下面的例子将演示Gitflow流程如何被用来管理一次产品发布。假设你已经创建好了一个中央仓库。

1. 创建develop分支

开发流程 - 图2

第一步是给默认的master配备一个develop分支。一种简单的做法是:让一个开发者在本地建立一个空的develop分支,然后把它推送到服务器。

  1. git branch develop
  2. git push -u origin develop

develop分支将包含项目的所有历史,而master会是一个缩减版本。现在,其他开发者应该克隆(clone)中央仓库,并且为develop创建一个追踪分支。

  1. git clone ssh://user@host/path/to/repo.git
  2. git checkout -b develop origin/develop

到现在,所有人都把包含有完整历史的分支(develop)在本地配置好了。

2. 小马和小明开始开发新功能

开发流程 - 图3

我们的故事从小马和小明要分别开发新功能开始。他们俩各自建立了自己的分支。注意,他们在创建分支时,父分支不能选择master,而要选择develop。

  1. git checkout -b some-feature develop

他们俩都在自己的功能开发分支上开展工作。通常就是这种Git三部曲:edit,stage,commit:

  1. git status
  2. git add <some-file>
  3. git commit

3. 小马把她的功能开发好了

开发流程 - 图4

在提交过几次代码之后,小马觉得她的功能做完了。如果她所在的团队使用“拉拽请求”,此刻便是一个合适的时机——她可以提出一个将她所完成的功能合并入develop分支的请求。要不然,她可以自行将她的代码合并入本地的develop分支,然后再推送到中央仓库,像这样:

  1. git pull origin develop
  2. git checkout develop
  3. git merge some-feature
  4. git push
  5. git branch -d some-feature

第一条命令确保了本地的develop分支拥有最新的代码——这一步必须在将功能代码合并之前做!注意,新开发的功能代码永远不能直接合并入master。必要时,还需要解决在代码合并过程中的冲突。

4. 小马开始准备一次发布

开发流程 - 图5

尽管小明还在忙着开发他的功能,小马却可以开始准备这个项目的第一次正式发布了。类似于功能开发,她使用了一个新的分支来做产品发布的准备工作。在这一步,发布的版本号也最初确定下来。

  1. git checkout -b release-0.1 develop

这个分支专门用于发布前的准备,包括一些清理工作、全面的测试、文档的更新以及任何其他的准备工作。它与用于功能开发的分支相似,不同之处在于它是专为产品发布服务的。
一旦小马创建了这个分支并把它推向中央仓库,这次产品发布包含的功能也就固定下来了。任何还处于开发状态的功能只能等待下一个发布周期。

5. 小马完成了发布

开发流程 - 图6

一切准备就绪之后,小马就要把发布分支合并入master和develop分支,然后再将发布分支删除。注意,往develop分支的合并是很重要的,因为开发人员可能在发布分支上修复了一些关键的问题,而这些修复对于正在开发中的新功能是有益的。再次提醒一下,如果小马所在的团队强调代码评审(Code Review),此时非常适合提出这样的请求。

  1. git checkout master
  2. git merge release-0.1
  3. git push
  4. git checkout develop
  5. git merge release-0.1
  6. git push
  7. git branch -d release-0.1

发布分支扮演的角色是功能开发(develop)与官方发布(master)之间的一个缓冲。无论什么时候你把一些东西合并入master,你都应该随即打上合适的标签。

  1. git tag -a 0.1 -m"Initial public release" master
  2. git push --tags

Git支持钩子(hook)的功能,也就是说,在代码仓库里某些特定的事件发生的时候,可以执行一些预定义的脚本。因此,一种可行的做法是:在服务器端配置一个钩子,当你把master推送到中央仓库或者推送标签时,Git服务器能为产品发布进行一次自动的构建。

6. 用户发现了一个bug

开发流程 - 图7

当一次发布完成之后,小马便回去与小明一起开发其他功能了。突然,某个用户提出抱怨说当前发布的产品里有一个bug。为了解决这个问题,小马(或者小明)基于master创建了一个用于维护的分支。她在这个分支上修复了那个bug,然后把改动的代码直接合并入master。

  1. git checkout -b issue-#001 master
  2. \# Fix the bug
  3. git checkout master
  4. git merge issue-#001
  5. git push

跟用于发布的分支一样,在维护分支上的改动也需要合并入develop分支,这一点是很重要的!因此,小马务必不能忘了这一步。随后,她就可以将维护分支删除。

  1. git checkout develop
  2. git merge issue-#001
  3. git push
  4. git branch -d issue-#001

参考

【1】GitHub 入门与实践
【2】Git 工作流程 | 阮一峰的网络日志
【3】Git 使用规范流程 | 阮一峰的网络日志
【4】Git 分支管理策略 | 阮一峰的网络日志
【5】您必须知道的 Git 分支开发规范
【6】git分支管理和工作流规范:具体规范
【7】Gitflow工作流程