release
分支是从develop
分支拉出、为版本发布做准备的临时分支.release
分支主要用于做最后时刻的bug修复以及发布相关信息的修改(比如,版本号、构建日期等).在release
分支做这些事情有助于develop
分支更清晰的合入下一个发布的特性.
从develop
分支拉出release
分支存在一个关键时刻.在那个时刻,develop
分支已经(基本)具备新发布想要的模样,至少所有本次发布需要的特性都已合入了develop
分支.所有未来发布的特性都不得合入develop
分支,必须等到那个时刻之后,release
分支拉出才能合入.
将要发布的版本号在release
分支拉出时确定.在此之前,develop
分支上的变更只是属于"下一个发布",但这个发布到底会是0.3还是1.0在release
分支拉出时明确,并遵循项目的版本号规则.
(黄色为develop
分支,绿色为release
分支,蓝色为master
分支)
release
分支从develop
分支创建而来.假设,当前已发布的版本是1.1.5
,我们马上要做一个新的发布.develop
分支已经具备发布条件,并且我们决定让这次发布的版本号是1.2
(不是1.1.6
也不是2.0
).因此,我们拉出release
分支,并用新版本号命名这个分支:
$ git checkout -b release-1.2 develop
Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
[release-1.2 74d9424] Bumped version number to 1.2
1 files changed, 1 insertions(+), 1 deletions(-)
创建完并切换分支后,我们变更了版本号(这里bump-version.sh是修改版本号的脚本),然后提交.
这个新分支会存在一段时间,直到发布完成.在这段时间内,新发现的bug需要修复在这个分支上,而不是develop
分支.新特性绝不允许再合入这个分支,而要合入develop
分支,等待下一次发布.
当release
分支的状态逐步稳定可以真正发布后,开始执行后续操作.首先,release
分支需要合入master
分支.然后,在master
分支上打tag,以便日后更容易指向这个历史版本.最后,在release
分支上的变更需要合回develop
分支,保证未来的发布也会包含这些bug修复.
前两个步骤(发布完成,打标签):
$ git checkout master
Switched to branch 'master'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2
把release
分支的变更合入develop
分支:
$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
这一步可能会引入合并冲突,因为我们变更了版本号.如果冲突,修复提交.
现在我们不再需要release
分支,需要删除:
$ git branch -d release-1.2
Deleted branch release-1.2 (was ff452fe).
在release
分支做最后的bug修复以及发布相关信息的修改(比如,版本号、构建日期等)有利于develop
分支更清晰的合入下一个发布的特性,版本收敛与下一个发布的特性开发互不影响.
下面以一个实例详细描述如何使用gitflow进行版本发布。
假设我们有一个git仓库(Hadoop),已经被gitflow初始化,develop-2.7.4
是develop
分支,master-2.7.4
是master
分支。此时,develop-2.7.4
已经具备了发布条件,所有准备在下一个发布交付的特性都已完成并合入develop-2.7.4
.develop-2.7.4
的版本号是8.1.1-SNAPSHOT
,也是我们下一个发布的版本号(这与我们上一节描述的版本号确定时间点不太一样,稍有提前,因为我们项目的版本号规则比较明确,所以在开始准备下一个发布时就已明确为8.1.1
,又因为是在开发中,所以有-SNAPSHOT
).
开始发布的第一个步骤是创建release
分支,因为发布版本号已确定为8.1.1
,所以release
分支以8.1.1
命名:
$ git flow release start 8.1.1
Switched to a new branch 'release/8.1.1'
Summary of actions:
- A new branch 'release' was created, based on 'develop-2.7.4'
- You are now on branch 'release/8.1.1'
Follow-up actions:
- Bump the version number now!
- Start committing last-minute fixes in preparing your release
- When done, run:
git flow release finish '8.1.1'
$ git branch
develop-2.7.4
master-2.7.4
* release/8.1.1
release/8.1.1
分支拉出后,当前发布开始.develop-2.7.4
可以开始合入下一个发布的特性,但是需要先将版本号改为下一个发布的版本号.按照项目版本号规则,下一个发布的版本号为8.2.1
,同时需要加上-SNAPSHOT
:
$ git checkout develop-2.7.4
Switched to branch 'develop-2.7.4'
Your branch is up-to-date with 'origin/develop-2.7.4'.
$ ./change-version.sh "2.7.4" "8.1.1" "-SNAPSHOT" "V20.18.40.R1.B1" "2.7.4" "8.2.1" "-SNAPSHOT" "V20.18.40.R2.B1"
...
<version>8.2.1-SNAPSHOT</version>
<version>2.7.4-zdh8.2.1-SNAPSHOT</version>
SUCCESS!!
$ git commit -am "Preparing for 8.2.1-SNAPSHOT development"
[develop-2.7.4 1655a61] Preparing for 8.2.1-SNAPSHOT development
1 file changed, 2 insertions(+), 2 deletions(-)
change-version.sh
是每个组件自己的版本号修改脚本,参数对应关系如下:
OPENSOURCE_RELEASE=$1 # 当前发布的开源组件版本号
ZDH_RELEASE=$2 # 当前发布的ZDH版本号
SNAPSHOT_TAG=$3 # 当前发布的SNAPSHOT标签
PRODUCT_RELEASE=$4 # 当前发布的产品完整版本号,可能会用于产品对外显示
OPENSOURCE_NEXT_RELEASE=$5 # 下一个发布的开源组件版本号
ZDH_NEXT_RELEASE=$6 # 下一个发布的ZDH版本号
NEXT_SNAPSHOT_TAG=$7 # 下一个发布的SNAPSHOT标签
PRODUCT_NEXT_RELEASE=$8 # 下一个发布的产品完整版本号,可能会用于产品对外显示
修改完之后,hadoop版本号变为2.7.4-zdh8.2.1-SNAPSHOT
:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.zte.zdh</groupId>
<artifactId>zdh-parent</artifactId>
<version>8.2.1-SNAPSHOT</version>
</parent>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-main</artifactId>
<version>2.7.4-zdh8.2.1-SNAPSHOT</version>
<description>Apache Hadoop Main</description>
<name>Apache Hadoop Main</name>
<packaging>pom</packaging>
将develop-2.7.4
的变更提交Gerrit评审:
$ git log HEAD --not origin/develop-2.7.4 # 确保本地develop-2.7.4上只有版本号的变更
commit b99e1ca4886fce9f2702b36f948c647e6b158d0e
Author: 何文鑫10087558 <[email protected]>
Date: Thu Jan 11 13:45:53 2018 +0800
Preparing for 8.2.1-SNAPSHOT development
Change-Id: Idb3ed63c29a7c6caeb26d098ac887b03cf3de11d
$ git push origin HEAD:refs/for/develop-2.7.4
...
因为release/8.1.1
会存在一段时间,用于bug修复,所以需要将release/8.1.1
推送到远端供bug修复:
$ git flow release publish 8.1.1
Warning: Permanently added '[gerrit.zte.com.cn]:29418,[10.41.103.20]:29418' (RSA) to the list of known hosts.
Warning: Permanently added '[gerrit.zte.com.cn]:29418,[10.41.103.20]:29418' (RSA) to the list of known hosts.
Total 0 (delta 0), reused 0 (delta 0)
remote: Processing changes: refs: 1, done
To ssh://[email protected]:29418/DAP/ZDH/Hadoop
* [new branch] release/8.1.1 -> release/8.1.1
Warning: Permanently added '[gerrit.zte.com.cn]:29418,[10.41.103.20]:29418' (RSA) to the list of known hosts.
Already on 'release/8.1.1'
Your branch is up-to-date with 'origin/release/8.1.1'.
Summary of actions:
- A new remote branch 'release/8.1.1' was created
- The local branch 'release/8.1.1' was configured to track the remote branch
- You are now on branch 'release/8.1.1'
release/8.1.1
拉出、develop-2.7.4
修改完版本号之后,下个发布的新特性可以开始合入develop-2.7.4
,而release/8.1.1
只做bug修复,不合新特性.
bug修复示意过程如下:
$ git checkout release/8.1.1
$ git commit -m "bugfix 1" && git push origin HEAD:refs/for/release/8.1.1
[release/8.1.1 cc62e0d] bugfix 1
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 bugfix.1
...
$ git commit -m "bugfix 2" && git push origin HEAD:refs/for/release/8.1.1
[release/8.1.1 53c844d] bugfix 2
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 bugfix.2
...
$ git commit -m "bugfix 3" && git push origin HEAD:refs/for/release/8.1.1
[release/8.1.1 4d39417] bugfix 3
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 bugfix.3
...
release/8.1.1
的bug修复可以定期合回develop-2.7.4
或者每次bug修复完成就合回,或者什么都不做,因为后续release/8.1.1
结束,那些没有被合回的修复还会被合回.到底采用哪种策略可根据实际情况确定.
建议尽早将修复都合回develop-2.7.4
,因为越早合回,冲突的概率越低.
合回使用如下操作(合回完成后需提交Gerrit评审):
$ git checkout develop-2.7.4
Switched to branch 'develop-2.7.4'
Your branch is up-to-date with 'origin/develop-2.7.4'.
$ git merge release/8.1.1 -m "Merge branch release/8.1.1 into develop-2.7.4"
Merge made by the 'recursive' strategy.
bugfix.1 | 0
bugfix.2 | 0
bugfix.3 | 0
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 bugfix.1
create mode 100644 bugfix.2
create mode 100644 bugfix.3
[develop-2.7.4 4ab5a6c] Merge branch release/8.1.1 into develop-2.7.4
Date: Thu Jan 11 15:31:56 2018 +0800
$ git commit --amend -C HEAD # 由于merge会产生一个空提交对象,但不会自动生成Change-Id,所以merge后使用commit --amend重新提交来生成Change-Id
$ git log
commit 8975b03c572b16686cbe5c50ddfd6b7b5cbe9235
Merge: 680a66e 4d39417
Author: 何文鑫10087558 <[email protected]>
Date: Thu Jan 11 15:05:40 2018 +0800
Merge branch release/8.1.1 into develop-2.7.4
Change-Id: If0a7e058f9c5dca928a67d3d98d4214b9121912a # Change-Id已经重新生成
commit 680a66e88e98a4ad4117ff94e1fa79d8dce884e5
Author: 何文鑫10087558 <[email protected]>
Date: Thu Jan 11 14:25:35 2018 +0800
bugfix 3
Change-Id: I36391cbdf465ace0d095f90c6616240f04d2aee0
$ git push origin HEAD:refs/for/develop-2.7.4 # 由于bug修复已经在release分支上评审过,此处不会再触发Gerrit评审,只有新生成的空提交需要评审,以便流水线验证整体合回是否影响到develop分支
Counting objects: 2, done.
Delta compression using up to 24 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 356 bytes | 0 bytes/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1)
remote: Processing changes: new: 1, refs: 1, done
remote:
remote: New Changes:
remote: http://gerrit.zte.com.cn/1347516 Merge branch release/8.1.1 into develop-2.7.4
remote:
To ssh://[email protected]:29418/DAP/ZDH/Hadoop
* [new branch] HEAD -> refs/for/develop-2.7.4
如果出现冲突,需要手工解决.
使用merge
命令而不推荐使用cherry-pick
合回release/8.1.1
的bug修复,主要是因为merge
会复用release/8.1.1
上的提交对象,而cherry-pick
会另生成一个提交对象,但另生成的对象与原对象的提交内容实际是一样的,所以使用merge
会让提交记录更整洁.
第二部分的过程会持续一段时间,直到release/8.1.1
的bug修复完成,功能趋于稳定.这个bug修复、功能收敛的过程越短越好.因为每次修复的bug都要合入两个分支,并且进行代码走查、流水线保护,无形增加了很多合入成本.因此要求我们在develop
分支上就要尽可能做好质量保障.
当release/8.1.1
趋于稳定后,可以开始结束发布的过程.
首先,将release/8.1.1
的全部变更合入master-2.7.4
:
$ git checkout master-2.7.4
Switched to branch 'master-2.7.4'
Your branch is up-to-date with 'origin/master-2.7.4'.
$ git merge --no-ff release/8.1.1
Auto-merging pom.xml
CONFLICT (content): Merge conflict in pom.xml
Automatic merge failed; fix conflicts and then commit the result.
这时会产生冲突,因为master-2.7.4
与release/8.1.1
对版本号都产生了变更,但变更后的值不一样.master-2.7.4
将版本号从7.8.1-SNAPSHOT
改为7.8.1
,而release/8.1.1
继承自develop-2.7.4
,将版本号从7.8.1-SNAPSHOT
改为8.1.1-SNAPSHOT
:
$ git diff pom.xml
diff --cc pom.xml
index 7d79ba7,28acb7e..0000000
--- a/pom.xml
+++ b/pom.xml
@@@ -27,11 -27,11 +27,19 @@@ xsi:schemaLocation="http://maven.apache
<parent>
<groupId>com.zte.zdh</groupId>
<artifactId>zdh-parent</artifactId>
++<<<<<<< HEAD
+ <version>7.8.1</version>
+ </parent>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-main</artifactId>
+ <version>2.7.3-zdh7.8.1</version>
++=======
+ <version>8.1.1-SNAPSHOT</version>
+ </parent>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-main</artifactId>
+ <version>2.7.4-zdh8.1.1-SNAPSHOT</version>
++>>>>>>> release/8.1.1
<description>Apache Hadoop Main</description>
<name>Apache Hadoop Main</name>
<packaging>pom</packaging>
这时只需要保留8.1.1-SNAPSHOT
这个版本就可以了,命令如下:
$ git checkout --theirs . # 此命令将所有的文件换成release/8.1.1的版本,相当于对所有冲突部分只保留release/8.1.1版本.
# 使用前需谨慎确保所有git status的变更文件都只是版本号相关文件,比如pom.xml,并且所有的冲突都是版本号相关
$ git add . # 将所有冲突修复后的文件加入暂存区
$ git commit -m "Merge branch release/8.1.1 into master-2.7.4"
此时,release/8.1.1
的全部变更就已合入master-2.7.4
:
$ git checkout master-2.7.4
$ git log
commit e180be234b00862cc49ede7af54892dba9ae5aa4
Merge: 4eabf5e 4d39417
Author: 何文鑫10087558 <[email protected]>
Date: Thu Jan 11 14:39:17 2018 +0800
Merge branch release/8.1.1 into master-2.7.4
Change-Id: I21f54ba7be946677d8878bc20ece800dcb249c75
commit 4d39417bf8cbb11ede1c94b57a64a5c5185afd5f
Author: 何文鑫10087558 <[email protected]>
Date: Thu Jan 11 14:25:35 2018 +0800
bugfix 3
Change-Id: I36391cbdf465ace0d095f90c6616240f04d2aee0
commit 53c844d458d3bb165d9d68e2205fc47f65dfded4
Author: 何文鑫10087558 <[email protected]>
Date: Thu Jan 11 14:25:15 2018 +0800
bugfix 2
Change-Id: I9f4a4b32ec6091a9aebd3cd9fdac0ffe1f721a00
commit cc62e0d19d4ee6daf548d40ed7f2fbf0db26e3fb
Author: 何文鑫10087558 <[email protected]>
Date: Thu Jan 11 14:25:05 2018 +0800
bugfix 1
Change-Id: Ia22e56fe92f42b3c7e719196920013a77ee5a831
commit 4eabf5e307d39ceaf65fe7f9eb878e28f2ed1959
Author: 何文鑫10087558 <[email protected]>
Date: Wed Jan 10 16:19:41 2018 +0800
Release for 7.8.1
Change-Id: I6532a84fc231338393f3c6a487d9074c42922a47
release/8.1.1
的全部变更合入master-2.7.4
后,准备在master-2.7.4
做正式发布,但之前需要在master-2.7.4
上将版本号去掉-SNAPSHOT
改为8.1.1
:
$ git checkout master-2.7.4
Switched to branch 'master-2.7.4'
Your branch is up-to-date with 'origin/master-2.7.4'.
$ ./change-version.sh "2.7.4" "8.1.1" "-SNAPSHOT" "V20.18.40.R1.B1" "2.7.4" "8.1.1" "" "V20.18.40.R2.B1"
...
<version>8.1.1</version>
<version>2.7.4-zdh8.1.1</version>
SUCCESS!!
$ git commit -am "Release for 8.1.1"
[master-2.7.4 5f31d41] Release for 8.1.1
1 file changed, 2 insertions(+), 2 deletions(-)
master-2.7.4
上完成所有变更后,master-2.7.4
上需要打tag标记,tag会被用来在master-2.7.4
上进行紧急bug修复.
tag操作:
$ git tag -a -m release-8.1.1 release-8.1.1 # 为了与分支release/8.1.1区分,tag命名为release-8.1.1
$ git show release-8.1.1
tag release-8.1.1
Tagger: 何文鑫10087558 <[email protected]>
Date: Wed Jan 10 14:02:25 2018 +0800
release-8.1.1
commit cbae556b0449ae1e0bd2eb079dbf1bc02c1818d8
Author: 何文鑫10087558 <[email protected]>
Date: Thu Jan 11 14:42:36 2018 +0800
Release for 8.1.1
Change-Id: I238662157a197f7107411ee79b0461e19f3dbaed
diff --git a/pom.xml b/pom.xml
index 28acb7e..db519f5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,11 +27,11 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
<parent>
<groupId>com.zte.zdh</groupId>
<artifactId>zdh-parent</artifactId>
- <version>8.1.1-SNAPSHOT</version>
+ <version>8.1.1</version>
</parent>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-main</artifactId>
- <version>2.7.4-zdh8.1.1-SNAPSHOT</version>
+ <version>2.7.4-zdh8.1.1</version>
<description>Apache Hadoop Main</description>
<name>Apache Hadoop Main</name>
<packaging>pom</packaging>
之前已经介绍过,应尽早将release/8.1.1
的bug修复合回develop-2.7.4
.
此时,我们仍需要再进行一次合回,确保所有的bug修复都已合回develop-2.7,4
.
操作过程同之前的合回过程,不再赘述.
上述操作完成后,可以删除release/8.1.1
了
$ git branch -d release/8.1.1
Deleted branch release/8.1.1 (was 39b1d0c).
确保develop-2.7.4
合回的所有变更都已提交,只有最后一个merge对象在Gerrit评审中:
$ git log develop-2.7.4 --not origin/develop-2.7.4
commit 4ab5a6c0bb0fb4d024193dfc2958f52a236fefe0
Merge: b99e1ca 4d39417
Author: 何文鑫10087558 <[email protected]>
Date: Thu Jan 11 15:31:56 2018 +0800
Merge branch release/8.1.1 into develop-2.7.4
Change-Id: Id4054075e9c4e7a8be19cc02a865a2c9878e98f4
将master-2.7.4
的变更提交到Gerrit评审:
$ git checkout master-2.7.4
Already on 'master-2.7.4'
Your branch is ahead of 'origin/master-2.7.4' by 6 commits.
(use "git push" to publish your local commits)
$ git push origin HEAD:refs/for/master-2.7.4
Warning: Permanently added '[gerrit.zte.com.cn]:29418,[10.41.103.20]:29418' (RSA) to the list of known hosts.
Counting objects: 4, done.
Delta compression using up to 24 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 631 bytes | 0 bytes/s, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2)
remote: Processing changes: new: 2, refs: 2, done
remote:
remote: New Changes:
remote: http://gerrit.zte.com.cn/1347860 Merge branch release/8.1.1 into master-2.7.4
remote: http://gerrit.zte.com.cn/1347861 Release for 8.1.1
remote:
To ssh://[email protected]:29418/DAP/ZDH/Hadoop
* [new branch] HEAD -> refs/for/master-2.7.4
删除远端release/8.1.1
:
$ git push origin --delete release/8.1.1
Warning: Permanently added '[gerrit.zte.com.cn]:29418,[10.41.103.20]:29418' (RSA) to the list of known hosts.
remote: Processing changes: refs: 1, done
To ssh://[email protected]:29418/DAP/ZDH/Hadoop
- [deleted] release/8.1.1
推送本地tag到远端保存:
$ git push origin release-8.1.1
Counting objects: 11, done.
Delta compression using up to 24 threads.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (11/11), 1.49 KiB | 0 bytes/s, done.
Total 11 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5)
remote: Processing changes: refs: 1, done
To ssh://[email protected]:29418/DAP/ZDH/Hadoop
! [remote rejected] release-8.1.1 -> release-8.1.1 (prohibited by Gerrit)
error: failed to push some refs to 'ssh://[email protected]:29418/DAP/ZDH/Hadoop'
结束发布过程完成.
最终,完整的各分支提交记录如下:
* abc15c7 (HEAD -> develop-2.7.4, origin/develop-2.7.4) Merge branch release/8.1.1 into develop-2.7.4
|\
* | b99e1ca Preparing for 8.2.1-SNAPSHOT development
| | * cbae556 (tag: release-8.1.1, origin/master-2.7.4, master-2.7.4) Release for 8.1.1
| | * e180be2 Merge branch release/8.1.1 into master-2.7.4
| | |\
| | |/
| |/|
| * | 4d39417 (release/8.1.1) bugfix 3
| * | 53c844d bugfix 2
| * | cc62e0d bugfix 1
|/ /
* | 031e952 Preparing for 8.1.1-SNAPSHOT development
| * 4eabf5e Release for 7.8.1
|/
|