git打tag的方法和技巧

使用git作为版本控制工具,在代码上线之前需要打tag,便于团队有条不紊地上线代码。在这里总结一下打tag的方法与可能用到的技巧。

打tag并上线的常规流程

一般是基于master分支打tag并推送tag到远程仓库,然后上线。要上线的代码合到master分支上之后,切换到master分支,pull最新代码,然后查看远程仓库的最新tag(假设为release_im_v0.0.9.8),在其基础上打tag release_im_v0.0.9.9。然后查看线上tag是哪一个(假设为release_im_v0.0.9.7),将新打的tag与线上tag进行diff,看代码有没有冲突,或者有没有别人合到master上但是暂时还不能上线的代码,如果没有问题,就可以把tag推送到远程仓库,然后请QA君帮忙上线。需要注意的是不能直接在线上tag的基础上加一作为新的tag,因为在你打tag期间团队其他人可能也打了tag,只是还没来得及上线而已,为避免冲突,需要基于远程仓库的最新tag打新tag。打tag并上线的流程如下:

1
2
3
4
5
6
7
8
$ git checkout master
$ git pull
$ git tag|grep im|tail #查看远程仓库含有im的最新tag
$ git tag -a release_im_v0.0.9.9 -m 'im咨询记录更改' #一般打含有附注的标签
$ git diff release_im_v0.0.9.7 release_im_v0.0.9.9 #如果改动比较多,也可以在gitlab上进行diff(当然要先push)
#如果diff没有问题,就可以把tag推送到远程仓库,远程仓库如果是origin,则可省略origin
$ git push [origin] release_im_v0.0.9.9 #推送具体的tag到远程仓库
$ git push [origin] --tags #一次推送所有的tag到远程仓库

如果diff有冲突,或者master分支上含有不能上线的代码,或者要修改一个线上的bug比较紧急,就需要基于线上tag拉分支,把自己的修改的代码应用到该分支,然后在该分支上打tag上线。需要注意的是,基于自己的分支打tag上完线,还是要把该分支合到master上,不然自己改动的代码会被后面基于master的tag所覆盖。

基于线上tag修改代码并上线

当需要解决线上bug比较紧急,则需要基于线上tag拉分支,在该分支修改代码并打tag上线。步骤如下(依然假设线上tag为release_im_v0.0.9.7,远程仓库最新tag为release_im_v0.0.9.8):

1
2
3
4
5
6
7
$ git fetch --tags                              #查看远程仓库的tag
$ git branch new_branch release_im_v0.0.9.7 #基于线上tag拉分支new_branch
$ git checkout new_branch #切到该分支并修改代码解决bug
$ git commit -am 'fix bug' #tag默认打在最新提交的commit上
$ git tag -a release_im_v0.0.9.9 -m 'fix bug'
$ git diff release_im_v0.0.9.7 release_im_v0.0.9.9
$ git push --tags

git cherry-pick的用法

当需要把某个分支的某次commit应用到另外一个分支,git cherry-pick命令就派上用场了。假设我们现在在a分支上,该分支上有一个commit(假设其哈希码为d986206)需要应用到b分支上,那么可以这么做:

1
2
3
4
$ git log --oneline       #查看a分支commit历史找到需要应用到b分支上的commit的哈希码为d986206
$ git show d986206 #确认commit内容
$ git checkout b
$ git cherry-pick d986206

基于线上tag打补丁并上线

假如我们在自己的test分支修改了很多代码,合到master之后发现master不能上线,而且该分支同时修改了两个相关的线上的tag(例如PC站和手机m站),需要分别把相应的修改应用到相应的tag上,并上线,由于commit的次数比较多,用cherry-pick就比较麻烦,这时我们就需要打补丁了。现在假设PC站线上tag和远程仓库最新tag都是release_www_v3.2.2.6,手机m站线上tag和远程仓库最新tag都是release_m_v3.0.8.3,运用第二部分中的方法基于线上tag分别拉取PC站和m站的分支www-patch和m-patch。
首先我们在自己的分支(这里是test分支)运行 git log –oneline 查看commit信息:
git log
发现544cf8c(主站获取id)、86721b7(m站获取id)、3971048(获取主站name)和f788477(获取m站name)这四次commit是需要上线的改动,于是我们将当前test分支与fb20a04(建立m类)这次commit进行diff以查看前四个commit的内容,确认无误后就可以打补丁了:

1
$ git diff fb20a04 test > patch

用vim打开patch文件截取部分如下:
patch
接下来切换到需要应用补丁的分支并应用该补丁:

1
2
3
4
5
6
$ git checkout www-patch
$ git apply patch #在www-patch分支应用补丁
$ git diff #查看应用补丁之后的diff以确认无误
$ rm patch #删除patch文件,git不需要追踪该文件,便于commit
$ git commit -am 'apply patch'
$ git tag -a release_www_v3.2.2.7 -m '打补丁上线'

当然也可以把patch文件放在~/目录下,假设代码文件夹也在~/目录下,然后这样打补丁:

1
2
3
4
5
$ git diff fb20a04 test > ~/patch
$ git checkout www-patch
$ patch -p1<~/patch
$ git commit -am 'apply patch'
$ git tag -a release_www_v3.2.2.7

接下来就是打手机m站的tag,这时我们就可以用git cherry-pick方法了,先在www-patch分支查看应用补丁的commit:
apply patch
然后应用到m-patch分支:

1
2
3
4
5
$ git checkout m-patch
$ git cherry-pick 584f3ef
$ git commit -am 'apply patch'
$ git tag -a release_m_v3.0.8.4 -m '打补丁上线'
$ git push --tags #最后把新打的tag都推送到远程仓库以上线

基于特定的commit打tag

假如我们想基于cf57ec4(建立www类)这次commit打tag,可以这样做:

1
$ git tag -a www0.9.9 cf57ec4 -m '建立www类'

运行git show www0.9.9命令查看该tag信息,可以看到是基于cf57ec4(建立www类)这次commit打的:
show tag
打tag时如果不指定commit,则默认基于当前分支的最新一次commit打。