Git/GitHub 分支标准和习惯

概述

用Git也有两年了,但是很多好的分支习惯都没有养成,前两天老大建议用git rebase解决本地冲突,惭愧的是以前连rebase这个命令都没了解过,有必要体系的学习一下Git的用法了,了解一下一些好的实践和还没有用到过的命令。本篇是GitHub上的一片文章,翻译过来,学习一下。

快速图例

实例 分支 描述,教例,笔记
Stable stable 接收来自Working和Hotfix的合并
Working master 接收来自Feature/Issue和Hotfix的合并
Feature/Issue topic-* 总是当前最新的Working的分支
Hotfix hotfix-* 总是Stable的分支

主要分支

主要库总是包含两个最常用的分支:

  • master
  • stable

主要分支应该是origin/master,该分支上的最新源码总是反应出下一个发布版最新的变化的状态。作为开发者,你需要从master上开分支,然后再合并回来。

可以把origin/stable当做总是表述为部署到生产环境的最新代码。stable分支不会每天都和最新的代码进行交互。

当master分支上的源码已经稳定却被部署了,所有的改变都会合并到stable分支上,并且打上发布号。这个步骤具体如何完成我们后面再讨论。

其他分支

其他分支用于在团队成员之间辅助并行开发,使跟踪特性更容易,并且有助于上线之后各种问题的快速修复。和主分支不一样,这些分支总是有一个优先的生命期限,它们最终会被移除掉。

可能用到的不同的分支类型有:

Feature分支
Bug分支
Hotfix分支

每一类分支都有特定的目的并遵循严格的规范,比如哪些分支是它们的起始分支,哪些分支又是它们的合并终点。接下来详细解释每个分支及其用法。

特性分支

特性分支用于开发有可能开发时间比一次发布周期还长的一个新特性或者新功能。开始开发时,可能无法确定新特性的具体在哪次版本发布。只要这个分支已经完成了,它就会被合并会master分支。

在特性的开发周期中,最新的代码时钟需要注意master分支(通过GitHub上的netword功能或者branch功能),查看从分支被创建起,master是否有新的提交。任何对master的改变都应该在当前分支合并回master分支前,被合并到当前分支中,这个操作可以重复多次,或者在最后再做也行,但应该注意处理合并冲突的次数。

特性分支

  • 必须是master的分支
  • 必须合并回master分支
  • 分支命名约定: feature-<分支号>
使用特性分支

如果分支还不存在,现在本地创建一个分支,然后将其push到GitHub上。一个特性分支应该总是公共可用的,这样做的意义在于,开发永远不应该只在一个开发者的本地分支上。

1
2
$ git checkout -b feature-id master                 // 为新特性创建一个本地分支
$ git push origin feature-id // 推到服务器,使公共可见

master上的改变(如果有的话)应该被定期合并到你的特性分支上。

1
$ git merge master                                  // 从master分支上合并新commits到特性分支

当一个分支上的开发已经结束,Leader应该将改变合并到master,然后确保服务器上的分支被删除。

1
2
3
4
$ git checkout master                               // 切换到master分支上
$ git merge --no-ff feature-id // 确保当合并时创建一个commit对象
$ git push origin master // push修改
$ git push origin :feature-id // 删除服务器上的分支

Bug分支

Bug分支和特性分支只是在语义上不同,当使用时有Bug时创建Bug分支,修复后合并到下一次部署中来。也因此,Bug分支的生存周期一般来说不会超过一次部署的循环周期。此外,Bug分支显式地区分了Bug分支和特性分支。无论Bug分支在什么时候完成,它永远都会被合并到master来中。

虽然可能性很小,在Bug修复的过程中,最新代码应该监听master分支,以检查是否在切出分支以来是否有新的提交。在Bug分支中合并回master分支之前,master分支的所所有改变都应该被合并到Bug分支中,这个操作可以在Bug分支的修复过程中或者结束时进行,但是注意要考虑处理冲突的时机。

Bug分支

  • 必须是master的分支
  • 必须合并回master分支
  • 分支命名约定:bug-<分支号>
使用Bug分支

如果Bug还不存在(检查最新代码),那就创建一个本地分支并将其推到GitHub。一个Bug分支应该总是公共可用的,这样做的意义在于,开发永远不应该只在一个开发者的本地分支上。

1
2
$ git checkout -b bug-id master                     // 为新bug创建一个本地分支
$ git push origin bug-id // 推送新分支到服务器

master上的改变(如果有的话)应该被定期合并到你的Bug分支上。

1
$ git merge master                                  // 合并新的commits到当前分支

当一个分支上的开发已经结束,Leader应该将改变合并到master,然后确保服务器上的分支被删除。

1
2
3
4
$ git checkout master                               // 切换到master分支
$ git merge --no-ff bug-id // 确保当合并时创建一个commit对象
$ git push origin master // push修改
$ git push origin :bug-id // 删除服务器上的分支

快速修复分支

快速修复分支(Hotfix分支)用于需要对生产版本(Stable分支)进行快速更新。另外,由于这种情况的紧急性,一个快速修复分支不需要被推到一个开发周期中去。由于这些需要,一个快速修复分支总是从stable分支切出,原因如下:

  • 快速修复分支提出之后master分支上可以继续开发。
  • 一个标记的stable分支仍然会在生产中使用。只要快速修复分支被需要,就可以有多个提交到master因为master已经不是最新的生产环境了。

Hotfix分支

  • 必须是stable的分支
  • 必须被合并回stable和master分支
  • 分支明明约定: hotfix-<分支号>
使用Hotfix分支

如果分支还不存在,先在本地创建分支,然后在推到GitHub上。一个快速修复分支应该总是公共可用的,这样做的意义在于,开发永远不应该只在一个开发者的本地分支上。

1
2
$ git checkout -b hotfix-id stable                  // 为新的快速修复创建一个分支
$ git push origin hotfix-id // 将新分支推到服务器

当快速修复已经完成,这些改变就应该被合并到stable中,并随后更新标签。

1
2
3
4
$ git checkout stable                               // 切换到stable分支
$ git merge --no-ff hotfix-id // 强制创建commit对象
$ git tag -a <tag> // 给修复打tag
$ git push origin stable --tags // 推送tag修改

最后将新的修改合并到master中以保证master也得到更新,然后删除远程快速修复分支。

1
2
3
4
$ git checkout master                               // 切换到master分支
$ git merge --no-ff hotfix-id // 强制创建commit对象
$ git push origin master // push修改
$ git push origin :hotfix-id // 删除服务器上的分支

工作流图例

参考

  1. Branching - digitaljhelms - Gist