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 的开发流程
以发布为中心的开发模式
标准工作流
- 从开发分支创建工作分支,进行功能的实现或修正
- 工作分支结束后与开发分支进行合并
- 重复 ① ② 直至功能可以发布
- 创建用于发布的分支,处理发布的各项工作
- 发布工作完成后与 master 分支合并,打上版本标签进行发布
- 如果发布的软件出现 BUG ,以打了标签的版本为基础进行修正
导入 Git Flow 的准备
- 安装 git-flow
- 仓库初始化
- 创建仓库
- 进行 git-flow 的初始化
- 在远程仓库也创建 develop 分支
Git Flow 工作流
master 分支与 develop 分支的区别
master 分支始终保持可发布的稳定状态,发布时必须包含版本标签。这个分支不允许开发者直接修改和提交。develop 分支是开发过程中的代码中心,这个分支和 master 分支一样不允许开发者直接修改和提交。程序员需要自己新建 feature 分支,在 feature 分支中开发和修正。也就是说,develop 分支维持着开发过程中的最新源代码。
在 feature 分支中的工作
- 从 develop 分支创建 feature 分支
- 在 feature 分支中实现目标功能
- 通过 GitHub 向 develop 分支发送 Pull Request
- 接收其他开发者审核后,将Pull Request 合并到 develop 分支
完成的 feature 适当时间进行删除
通过代码审查实现代码质量的提升
- 由其他开发者进行代码审查,反馈在 Pull Request 中
- 修正代码反馈的内容
- 将修改后特征分支推送到远端(自动添加到之前的 Pull Request)
- 重复前三步
- 确认 Pull Request 没有问题,合并到 develop 分支
反馈的几个要点:
- 没有测试or未通过测试
- 违反编码原则
- 代码品质过低(命名不明确, 方法冗长)
- 还有重构的余地
- 有重复的部分
在 release 分支的工作
- 创建分支
以最新的 develop 分支创建一个发布分支
- 分支内的工作
只处理与发布前有关的提交,如:版本编号变更、bug 的修正。该分支不能包含功能的添加、变更等内容
- 进行发布与合并
合并至 master 将项目发布
- 查看版本标签
$ 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分支
第一步是给默认的master配备一个develop分支。一种简单的做法是:让一个开发者在本地建立一个空的develop分支,然后把它推送到服务器。
git branch develop
git push -u origin develop
develop分支将包含项目的所有历史,而master会是一个缩减版本。现在,其他开发者应该克隆(clone)中央仓库,并且为develop创建一个追踪分支。
git clone ssh://user@host/path/to/repo.git
git checkout -b develop origin/develop
到现在,所有人都把包含有完整历史的分支(develop)在本地配置好了。
2. 小马和小明开始开发新功能
我们的故事从小马和小明要分别开发新功能开始。他们俩各自建立了自己的分支。注意,他们在创建分支时,父分支不能选择master,而要选择develop。
git checkout -b some-feature develop
他们俩都在自己的功能开发分支上开展工作。通常就是这种Git三部曲:edit,stage,commit:
git status
git add <some-file>
git commit
3. 小马把她的功能开发好了
在提交过几次代码之后,小马觉得她的功能做完了。如果她所在的团队使用“拉拽请求”,此刻便是一个合适的时机——她可以提出一个将她所完成的功能合并入develop分支的请求。要不然,她可以自行将她的代码合并入本地的develop分支,然后再推送到中央仓库,像这样:
git pull origin develop
git checkout develop
git merge some-feature
git push
git branch -d some-feature
第一条命令确保了本地的develop分支拥有最新的代码——这一步必须在将功能代码合并之前做!注意,新开发的功能代码永远不能直接合并入master。必要时,还需要解决在代码合并过程中的冲突。
4. 小马开始准备一次发布
尽管小明还在忙着开发他的功能,小马却可以开始准备这个项目的第一次正式发布了。类似于功能开发,她使用了一个新的分支来做产品发布的准备工作。在这一步,发布的版本号也最初确定下来。
git checkout -b release-0.1 develop
这个分支专门用于发布前的准备,包括一些清理工作、全面的测试、文档的更新以及任何其他的准备工作。它与用于功能开发的分支相似,不同之处在于它是专为产品发布服务的。
一旦小马创建了这个分支并把它推向中央仓库,这次产品发布包含的功能也就固定下来了。任何还处于开发状态的功能只能等待下一个发布周期。
5. 小马完成了发布
一切准备就绪之后,小马就要把发布分支合并入master和develop分支,然后再将发布分支删除。注意,往develop分支的合并是很重要的,因为开发人员可能在发布分支上修复了一些关键的问题,而这些修复对于正在开发中的新功能是有益的。再次提醒一下,如果小马所在的团队强调代码评审(Code Review),此时非常适合提出这样的请求。
git checkout master
git merge release-0.1
git push
git checkout develop
git merge release-0.1
git push
git branch -d release-0.1
发布分支扮演的角色是功能开发(develop)与官方发布(master)之间的一个缓冲。无论什么时候你把一些东西合并入master,你都应该随即打上合适的标签。
git tag -a 0.1 -m"Initial public release" master
git push --tags
Git支持钩子(hook)的功能,也就是说,在代码仓库里某些特定的事件发生的时候,可以执行一些预定义的脚本。因此,一种可行的做法是:在服务器端配置一个钩子,当你把master推送到中央仓库或者推送标签时,Git服务器能为产品发布进行一次自动的构建。
6. 用户发现了一个bug
当一次发布完成之后,小马便回去与小明一起开发其他功能了。突然,某个用户提出抱怨说当前发布的产品里有一个bug。为了解决这个问题,小马(或者小明)基于master创建了一个用于维护的分支。她在这个分支上修复了那个bug,然后把改动的代码直接合并入master。
git checkout -b issue-#001 master
\# Fix the bug
git checkout master
git merge issue-#001
git push
跟用于发布的分支一样,在维护分支上的改动也需要合并入develop分支,这一点是很重要的!因此,小马务必不能忘了这一步。随后,她就可以将维护分支删除。
git checkout develop
git merge issue-#001
git push
git branch -d issue-#001
参考
【1】GitHub 入门与实践
【2】Git 工作流程 | 阮一峰的网络日志
【3】Git 使用规范流程 | 阮一峰的网络日志
【4】Git 分支管理策略 | 阮一峰的网络日志
【5】您必须知道的 Git 分支开发规范
【6】git分支管理和工作流规范:具体规范
【7】Gitflow工作流程