前言

在当前公司的软件发布流程中,发现原来使用git-flow的分支发布方式存在诸多弊端,于是我们寻求一种相较更好的发布流程,于是就盯上了tag发布。本篇文章旨在介绍tag的使用基础,以及我们是如何将tag应用到正常的软件发布迭代中去。该方案仅供参考。

1、Tag命令基础

Git tag分为两种类型:带注释的tag和轻量级的tag。两种都允许你在你的repo中标记一个专用的commit,只是在存储原数据上有些不同。

1.1、带注释的tag

带注释的tag会携带一些额外的信息,比如作者的名字、版本发布信息、tag信息以及时间。使用下面这个命令完成带注释的tag:

git tag -a v1.0.0

或者

git tag v1.0.0 -m 'xxxx'

打完带注释的tag,当你查看该tag的时候会显示如下信息:

1.2、轻量级的tag

轻量级的tag是一种以最简单地方式在你的repo里添加tag,因为它只会存储你引用的commit的hash值。只要不使用上述的参数-a-m-s创建出来的就都是这种类型tag。当我们show轻量级的tag的时候出来的是这种结果:

1.3、其他命令

  • git tag: 列举所有存在的tag
    • -l 可以过滤你想查看的tag名称,支持通配符,比如git tag -l 'v1.0.*',就可以查看v1.0.*的所有存在的tag
    • -n 可以查看tag的注释内容,默认值查看一行,如果想查看多行的话后面加个数字即可,比如:-n3
    • --sort=<type> 可以给查看的tag排个序,支持的排序参数:refname/version:refname(v:refname)
  • git show: 显示某个特定的tag信息
  • git tag -a -f <tag名称> <新的commit ID>: 该命令可以更新已经打好的tag指向的commit ID。正常我们更新某个已经存在的tag的时候,会报错:fatal: tag 'v1.0.0' already exists, 所以我们可能会去先删除远程tag和本地tag,然后再重新打一个新的tag。现在这个流程可以直接使用这个命令一步到位了。 NOTE:该命令有明显的副作用,使用的时候谨慎再谨慎!
  • git tag -d <tag名称>: 删除本地指定的tag,本地删除之后如果想同步到远程: git push origin :tag名称
  • git push origin tag名称(git push --tags): 推送本地指定tag或者全部的tags到远程

2、Tag在软件发布的实践

因为目前软件发布的频繁迭代(一天之内可能连续上好几个需求),以及发布环境(有线上环境和灰度测试环境)的越发复杂,原本的gitflow工作流或者分支发布满足不了我们的正常需要,于是我们使用git tag去寻找一个相对更优雅的发布流程。 下图是我们当前软件发布的流程:

该流程遵循以下规范:

  • 所有的新需求fork的代码都是从master拉出新分支,并命名为feature/xxx(xxx为需求名称)
  • hotfix分支代码永远都是从线上稳定运行的tag上fork出来的代码
  • 所有开发完成的feature分支都会合并到develop分支
  • feature分支代码测试完毕后都合并到master,并打上对应的tag同步给测试进行主干回归
  • 按照上线时间给所有的需求指定一个自己独一无二的tag,一般都是vx.x.x来排序所有的需求
  • hotfix修改后的代码需要同步到所有高于线上稳定运行的tag的分支上,这个可以使用autoHotfixTag.sh脚本来自动完成。

2.1、autoHotdixTag脚本介绍

该脚本使用Shell语言编写,使用规则是:

sh autoHotfixTag.sh <vx.x.x> <commitId,commitId> <message>

其中:

  • v.x.x表示的是你想要将commit应用到那些大于vx.x.x的所有存在的tag之上
  • 表示的是你想要应用的commitId列表,使用,分割开来多个commit
  • 表示你想要在新更新的tag之上加上什么新的注释信息。

脚本实现的原理大家可以自行去脚本里寻找,其实都是很简单的思路,就不再赘述了。

参考

  1. A Tutorial for Tagging Releases in Git