hello云胜

技术与生活

0%

git-flow实践

git-flow有两个涵义,一个是指软件开发领域的版本管理流程Gitflow。另一个是指git命令工具git flow。

目前业界主流的版本管理流程是Gitflow 和 trunk-based。

Gitflow流行的比较早。但是目前的流行度要低于 trunk-based模式工作流。trunk-based模式被誉为是现代化持续结成的最佳实践。

他俩的核心区别是,Gitflow是一个更严格的流程,只需要特性的管理员来批准代码可以合入主干。这样可以保证主干分支的代码质量。

而trunk-based流程相对而言更开放,所有开发者都有权限合入主干,以此来达到团队快速迭代功能的目标。

但是,在很多注重质量的大型公司,出于对主干代码的控制权考虑,还是会使用Gitflow 工作流(或其变种)。

我们通过结合使用git-flow工具来了解Gitflow工作流。

安装git-flow工具

git-flow工具是进行Gitflow实践的有力工具。

windows下安装很简单,其实就是安装git工具。安装好之后,git flow就已经可以使用了。

下载https://git-scm.com/download/win

image-20230419112959938

使用

git-flow工具实际上就是git命令的包装。执行一个git flow命令相当于标准的 Git 命令用脚本组合了起来进行执行。

所以git-flow工具并没有什么神奇之处。只是会让你的操作更加高效。

在一个新项目上进行测试。

init

git flow init进行git仓库的初始化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ git flow init
Initialized empty Git repository in D:/temp/gitflow/.git/
No branches exist yet. Base branches must be created now.
Branch name for production releases: [master]
Branch name for "next release" development: [develop]

How to name your supporting branch prefixes?
Feature branches? [feature/]
Bugfix branches? [bugfix/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []
Hooks and filters directory? [D:/temp/gitflow/.git/hooks]

git flow的初始化,相比于git init的初始化,会自动创建分支。

gitflow工作流主要使用两个分支。

![01 How it works](D:\github\docs\git\Gitflow实践.assets\01 How it works-16818869602003.svg)

master分支是生产分支。不能直接工作在这个 master 分支上。不直接提交改动到 master 分支上是gitflow工作流程的一个基本规则。在master分支通过tag切出生产版本。

develop分支是开发分支。是我们进行任何新的开发的基础分支。比如新的特性分支从develop分支上拉出来。

一般最好就保持默认的分支名字。

这两个分支被称作为 长期分支。它们会存活在项目的整个生命周期中。

而其他的分支,例如针对功能的分支,针对release的分支,仅仅只是临时存在的。它们是根据需要来创建的,当它们完成了自己的任务之后就会被删除掉。

初始化时会设定这些功能分支的前缀名。

1
2
3
$ git branch -a
* develop
master

feature branch

进行新的功能开发时,我们应该切出一个新的特性分支。

feature branch是从develop分支切出。

功能开发完成后,feature 分支也是merge会develop分支,feature 分支不应该直接同main分支发生联系。

![02 Feature branches](D:\github\docs\git\Gitflow实践.assets\02 Feature branches.svg)

创建feature分支

使用git flow创建一个feature分支

1
2
3
4
5
6
7
8
9
10
11
$ git flow feature start add-user
Switched to a new branch 'feature/add-user'

Summary of actions:
- A new branch 'feature/add-user' was created, based on 'develop'
- You are now on branch 'feature/add-user'

Now, start committing on your feature. When done, use:

git flow feature finish add-user

我创建一个名为add-user的特性分支。gitflow会自动加上feature前缀。

这里执行的git操作其实就是

1
2
git checkout develop
git checkout -b add-user

提交分支

在我们开发完成这个功能后,需要把提交merge回develop分支。

如果直接使用git,应该这么操作

1
2
git checkout develop
git merge add-user

现在使用git flow,直接这样写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ git flow feature finish add-user
Switched to branch 'develop'
Updating e38e2e6..744118e
Fast-forward
AddUser.java | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 AddUser.java
Deleted branch feature/add-user (was 744118e).

Summary of actions:
- The feature branch 'feature/add-user' was merged into 'develop'
- Feature branch 'feature/add-user' has been locally deleted
- You are now on branch 'develop'

并且会自动将feature/add-user删除

release branch

在一个开发周期内,我们在创建feature分支,开发完成,合并回develop。当所有的功能都开发完了,或者预定的发版日快到了时,我们就需要切出一个release分支,用来发预生产测试。

release分支也是从develop分支切出的。

release分支切出后,新的feature不应该合入release分支,只有紧急的bug修复,或者文档类工作可以合入。

如果这个release要进行交付,那么将个release分支合入main主干分支,并打上tag。

并且,这个release分支也要merge回develop分支,因为可能有了新的修改。

![03 Release branches](D:\github\docs\git\Gitflow实践.assets\03 Release branches.svg)

通过release分支,可以很好的控制开发节奏。也就是版本火车。

创建release分支

使用git flow创建一个release分支:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ git flow release start 0.1.0
Switched to a new branch 'release/0.1.0'

Summary of actions:
- A new branch 'release/0.1.0' was created, based on 'develop'
- You are now on branch 'release/0.1.0'

Follow-up actions:
- Bump the version number now!
- Start committing last-minute fixes in preparing your release
- When done, run:

git flow release finish '0.1.0'

注意,release 分支是使用版本号命名的。这是一个最佳实践。当我们完成了release 后,git-flow 会自动去标记那些 release 提交。

然后我们会拿这个版本的release分支去测试。完成后就拿去发版了。

发布release

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ git flow release finish 0.1.0
Switched to branch 'master'
Merge made by the 'recursive' strategy.
AddUser.java | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 AddUser.java
Already on 'master'
Switched to branch 'develop'
Already up to date!
Merge made by the 'recursive' strategy.
Deleted branch release/0.1.0 (was 744118e).

Summary of actions:
- Release branch 'release/0.1.0' has been merged into 'master'
- The release was tagged '0.1.0'
- Release tag '0.1.0' has been back-merged into 'develop'
- Release branch 'release/0.1.0' has been locally deleted
- You are now on branch 'develop'

发布release做的事情就是

  • merge到master
  • merge回develop
  • 删除release 分支
  • 切到develop分支

hotfix branch

很多时候,我们会发现已经release出的版本有bug,hotfix分支就是进行已发布产品bug修复的分支。

![04 Hotfix branches](D:\github\docs\git\Gitflow实践.assets\04 Hotfix branches.svg)

创建hotfix分支

创建的命令和之前的很相似

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ git flow hotfix start userbug-fix
Switched to a new branch 'hotfix/userbug-fix'

Summary of actions:
- A new branch 'hotfix/userbug-fix' was created, based on 'master'
- You are now on branch 'hotfix/userbug-fix'

Follow-up actions:
- Start committing your hot fixes
- Bump the version number now!
- When done, run:

git flow hotfix finish 'userbug-fix'

hotfix分支特殊之处在于它是从main主干分支上切出来的。

这也是唯一会从main主干分支上切出来的一种分支。

完成修复

当hotfix分支完成修复后,要merge到main分支,并打上新的tag

同时也要merge回到develop分支

1
2
3
4
5
6
7
8
9
10
$ git flow hotfix finish userbug-fix
Switched to branch 'develop'
Deleted branch hotfix/userbug-fix (was cfbf979).

Summary of actions:
- Hotfix branch 'hotfix/userbug-fix' has been merged into 'master'
- The hotfix was tagged 'userbug-fix'
- Hotfix branch 'hotfix/userbug-fix' has been locally deleted
- You are now on branch 'develop'

总结

Gitflow工作流是众多基于git的工作流中的一种。

尤其适合于基于release版本的工作流程。

Gitflow工作流基于master主干分支和develop开发分支,这俩个长期分支。

以及hotfixes, features, 和releases三个不同功能的临时性功能分支。

这三个分支根据其角色不同,又会有不同的合并策略。

git flow工具是git命令的一个小扩展。主要作用是标准化了切分支,merge分支的流程。

使用git flow工具不是执行Gitflow工作流的必要条件。但是是执行Gitflow工作流的一个最佳实践。

gitflow的缺点:

开发者根据业务需求,创建自己的特性分支进行功能开发,这会是一个生命时间很长的分支,直到完成并测试通过了这个功能特性,这个分支的代码才会允许合并入主干。

这就可能导致大量的合并冲突。

并且gitflow会创建多个不同角色的分支,这进一步增加了分支管理的复杂性。