介绍

Git Flow 是由Vincent Driessen在2010年提出的一种Git工作流。在这之前,Git没有一个明确的标准工作流,导致团队在使用Git时往往会遇到一些问题,如分支管理、版本控制等。为了解决这些问题,Vincent Driessen提出了Git Flow分支模型,成为了Git在实际应用中的一种标准工作流。

随着时间的推移,Git Flow也在不断发展和完善。在2011年,Atlassian发布了SourceTree,这是一款图形化的Git客户端,支持Git Flow分支模型。在2013年,Git Flow的一些开发者发布了Git Flow AVH Edition,这是Git Flow的一个增强版本,提供了更多的功能和选项。此外,Git Flow还得到了其他开源工具和平台的支持,如GitHub、GitLab等。

Git Flow 分支模型

Git Flow分支模型定义了一种标准的Git分支模型,它将代码分为两个长期分支(master和develop)和三个短期分支(feature、release和hotfix),使得团队可以更好地管理代码的版本和发布。

以下是Git Flow分支模型的详细介绍:

  1. master分支 master分支是代码库的主分支,它包含了所有已发布的代码和版本。所有代码都应该在该分支上进行测试和验证,以确保代码的质量和稳定性。master分支只能通过合并release或hotfix分支来更新
  2. develop分支 develop分支是代码库的开发分支,它包含了所有开发中的代码和功能。所有新的代码都应该在该分支上进行开发和测试,以确保代码的可靠性和稳定性。develop分支只能通过合并feature分支来更新
  3. feature分支 feature分支是为开发新的功能或修复bug而创建的临时分支。每个feature分支都是从develop分支分离出来的,开发完成后会合并回develop分支。feature分支的命名应该清晰明确,以反映该分支所涉及的功能或问题。
  4. release分支 release分支是为发布新版本而创建的临时分支。每个release分支都是从develop分支分离出来的,发布完成后会合并回develop分支和master分支。在release分支上可以进行一些小的修复和调整,以确保发布的代码的质量和稳定性。
  5. hotfix分支 hotfix分支是为快速修复生产环境中的问题而创建的临时分支。每个hotfix分支都是从master分支分离出来的,修复完成后会合并回develop分支和master分支。hotfix分支的优先级比其他分支更高,因为它们需要尽快修复生产环境中的问题。

img

根据上面的理论,我们来实际操作一遍。首先,是 develop 分支创建一个 feature 分支。

$ git checkout -b feature-test develop
Switched to a new branch "feature-test"

将 feature 分支的修改合并到 develop 分支,然后删除 feature 分支:

$ git checkout develop
Switched to branch 'develop'

$ git merge --no-ff feature-test
Updating ea1b82a..05e9557
(Summary of changes)

$ git branch -d feature-test
Deleted branch feature-test (was 05e9557).

$ git push origin develop

合并分支时,添加--no-ff 参数和不添加的区别:

img

从 develop 分支创建一个 release 分支,并将版本号改为 1.2 :

$ 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(-)

release 分支完成开发之后,将 release 分支合并到 master 分支,并创建一个标签:

$ 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).

对于 hoftfix 分支,操作步骤和 release 分支类似,故不在赘述。

git-flow 工具

git-flow 工具可以简化上面的操作步骤,关于 git-flow的介绍可以参考文章:Using git-flow to automate your git branching workflow

macos 上安装 git-flow:

brew install git-flow

git-flow 首先需要初始化,如果不存在 develop 分支,则会新建一个 develop 分支:

git flow init
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-]
Release branches? [release-]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []

feature 分支

开发一个新功能,创建一个新分支 foo

$ git flow feature start foo

等价于

#切换到develop分支,确保新的 feature 分支是基于最新的 develop 分支创建的。
$ git checkout -b feature-foo develop

取消正在进行中的功能分支,并且会将分支删除

$ git flow feature delete foo

等价于

$ git branch -D feature-foo

foo 功能自测通过后,合并到 develop

$ git flow feature finish foo

等价于

//切换到 develop 分支
$ git checkout develop
//将 feature-foo 分支中的更改合并到 develop 分支。 --no-ff 参数将保留 foo 分支的commit记录。
$ git merge --no-ff feature-foo
//删除已完成的分支
$ git branch -d feature-foo

release 分支

当所有新的功能和必要的修复已经被彻底的测试过了,那就开始生成一个新的 release , 在此之后不能添加新功能,只有错误修复、文档生成和其他面向发布的任务应该在该分支中进行。

# 1.0.0 是版本号
$ git flow release start 1.0.0

等价于

# 从 develop 分支 创建release分支
$ git checkout -b release-1.0.0 develop

取消正在进行中的发布分支,并且会将分支删除。

$ git flow release delete 1.0.0

等价于

git branch -D release-1.0.0

添加完发布文档之后,完成 release

$ git flow release finish 1.0.0

等价于

#切换到 develop 分支。
$ git checkout develop
#将 release-1.0.0 分支合并到 develop 分支,--no-ff 选项以保留 feature 分支的 commit 记录
$ git merge --no-ff release-1.0.0
#创建一个名为 1.0.0 的标签
$ git tag -a 1.0.0 -m "Release 1.0.0"
#切换到 master 分支。
$ git checkout master
#将 release-1.0.0 分支合并到 master 分支,--no-ff 选项以保留 feature 分支的 commit 记录
$ git merge --no-ff release-1.0.0
#删除 release-1.0.0 分支。
$ git branch -d release-1.0.0

Hotfixes 分支

线上发生问题的时候,先回滚到之前的稳定版本,稳定局势 然后创建热修复分支开始改 BUG

$ git flow hotfix start 1.0.1

等价于

#从master分支 创建一个hotfix/1.0.1分支
$ git checkout -b hotfix/1.0.1 foo master

紧急修复完毕

$ git flow hotfix finish 1.0.1

等价于

#切换 master 分支
$ git checkout master
#合并热修复分支到master,--no-ff 选项以保留 feature 分支的 commit 记录
$ git merge --no-ff hotfix/ohno
#创建一个名为 1.0.1 的标签
$ git tag 1.0.1
#切换到 develop 分支
$ git checkout develop
#合并热修复分支到 develop ,--no-ff 选项以保留 feature 分支的 commit 记录
$ git merge --no-ff hotfix/1.0.1
#删除热修复分支
$ git branch -d hotfix/1.0.1

git-flow (AVH Edition)

Git-flow (AVH Edition)是Git Flow的一个增强版本,由一些Git Flow的开发者开发和维护。Git-flow (AVH Edition)在保留Git Flow基本思想的前提下,增加了一些新的功能和选项,使得Git Flow更加灵活和适用于不同的团队和项目。

Git-flow (AVH Edition)的主要增强功能包括:

  1. 支持git-flow init命令,可以在一个新的Git仓库中快速初始化Git Flow。
  2. 支持git flow feature pull命令,可以拉取其他团队成员的feature分支。
  3. 支持git flow feature publish命令,可以将feature分支发布到远程仓库。
  4. 支持git flow hotfix finish命令,可以在修复生产环境问题时自动合并到develop分支和master分支并发布新版本。
  5. 支持git flow support分支,可以为旧版本提供长期支持。
  6. 允许使用Hooks and Filters来扩展和自定义Git Flow的行为。

除了以上功能之外,Git-flow (AVH Edition)还提供了更多的选项和配置,使得团队可以根据不同的需求和情况来自定义Git Flow的分支模型和工作流程。

初始化

使用下面命令初始化 git fow,-d 是可选参数,表示使用默认参数:

git flow init [-d]

创建 feature/release/hotfix/support 分支

查看、开始、完成、删除 feature 分支:

git flow feature

# <base> 参数必须是分支名称,缺失时,默认为 develop 分支
git flow feature start <name> [<base>]

git flow feature finish <name>

git flow feature delete <name>

发布或者跟踪 feature 分支:

#如果当前在 feature/name 分支,则可以省略 <name> 参数
git flow feature publish <name>
git flow feature track <name>

当 feature 分支发布之后,其他人可以拉取该分支:

git pull
git checkout feature/<name>

类似地,查看、开始、完成、删除 release 分支:

git flow release
git flow release start <name> [<base>]
git flow release finish <name>
git flow release delete <name>

类似地,查看、开始、完成、删除 hotfix 分支:

git flow hotfix
git flow hotfix start <name> [<base>]
git flow hotfix finish <name>
git flow hotfix delete <name>

查看、开始 support 分支:

git flow support
git flow support start <name> <base>

Hooks 和 Filters

Git-flow (AVH Edition)允许使用Hooks and Filters来扩展和自定义Git Flow的行为。Hooks和Filters是Git Flow中的两个关键概念,它们可以在Git Flow的不同阶段执行自定义脚本或命令,从而实现Git Flow的高度定制化。

Hooks是一些脚本或命令,它们会在Git Flow的不同阶段被调用。Git Flow (AVH Edition)支持以下Hooks:

  1. git-flow-init: 该Hook会在git-flow init命令执行时被调用。
  2. git-flow-feature-start: 该Hook会在创建新的feature分支时被调用。
  3. git-flow-feature-finish: 该Hook会在完成feature分支时被调用。
  4. git-flow-release-start: 该Hook会在创建新的release分支时被调用。
  5. git-flow-release-finish: 该Hook会在完成release分支时被调用。
  6. git-flow-hotfix-start: 该Hook会在创建新的hotfix分支时被调用。
  7. git-flow-hotfix-finish: 该Hook会在完成hotfix分支时被调用。

Filters是一些命令或参数,它们会在Git Flow的不同阶段被过滤或修改。Git Flow (AVH Edition)支持以下Filters:

  1. git-flow-feature-start-message: 可以用于修改feature分支创建时的提交信息。
  2. git-flow-feature-finish-message: 可以用于修改feature分支完成时的提交信息。
  3. git-flow-release-start-message: 可以用于修改release分支创建时的提交信息。
  4. git-flow-release-finish-message: 可以用于修改release分支完成时的提交信息。
  5. git-flow-hotfix-start-message: 可以用于修改hotfix分支创建时的提交信息。
  6. git-flow-hotfix-finish-message: 可以用于修改hotfix分支完成时的提交信息。

下面是一些使用Hooks和Filters的例子:

  1. 使用git-flow-init Hook

如果需要在执行git-flow init命令时执行一些自定义脚本,可以使用git-flow-init Hook。假设我们想在git-flow init命令执行时输出一些信息,可以在.git/hooks/git-flow-init文件中添加以下内容:

#!/bin/bash

echo "Executing git-flow-init Hook"
  1. 使用git-flow-feature-start Hook

如果需要在创建新的feature分支时执行一些自定义脚本,可以使用git-flow-feature-start Hook。假设我们想在创建新的feature分支时自动为该分支设置一些默认值,可以在.git/hooks/git-flow-feature-start文件中添加以下内容:

#!/bin/bash

# Set default values for feature branch
git config branch.$GIT_BRANCH_NAME.some_config_value "default_value"
  1. 使用git-flow-feature-finish-message Filter

如果需要修改feature分支完成时的提交信息,可以使用git-flow-feature-finish-message Filter。假设我们想在feature分支完成时强制要求填写提交信息,可以在.git/config文件中添加以下内容:

[gitflow "feature"]
    finishmessage = Please provide a meaningful commit message for the feature branch
  1. 使用 git-flow-hotfix-start Hook

如果需要在创建新的hotfix分支时执行一些自定义脚本,可以使用git-flow-hotfix-start Hook。假设我们想在创建新的hotfix分支时自动为该分支设置一些默认值,可以在.git/hooks/git-flow-hotfix-start文件中添加以下内容:

#!/bin/bash

# Set default values for hotfix branch
git config branch.$GIT_BRANCH_NAME.some_config_value "default_value"
  1. 使用 git-flow-hotfix-finish Hook

.git/hooks/git-flow-hotfix-finish文件中添加以下内容:

#!/bin/bash

# Update version number in package.json
VERSION=$(cat package.json | jq -r '.version')
NEW_VERSION=$(echo $VERSION | awk -F. '{$NF++;print}' | sed 's/ /./g')
sed -i '' "s/\"version\": \"$VERSION\"/\"version\": \"$NEW_VERSION\"/g" package.json

该脚本用于修改前端项目中的版本号。

GitHub Flow 模型

GitHub Flow是一种基于GitHub的分支模型和代码开发工作流程,它是一个简单而灵活的模型,在敏捷开发和持续交付方面具有很高的效率。相比于Git Flow,GitHub Flow更加适合团队和开发者进行快速迭代和快速上线。

GitHub Flow的分支模型非常简单:只有一个主分支(通常是master分支)和多个特性分支。主分支始终处于稳定状态并用于生产环境。每个特性分支用于开发新功能或修复bug,并在开发人员完成相应的开发和测试工作后合并到主分支中。

github flow

GitHub Flow 遵循以下 6 条原则:

  1. master 分支永远是随时可部署发布的
  2. 需求新增基于 master 分支,并创建一个语义化分支
  3. 定期推送本地分支到远端
  4. 合并到 master 需要提 PR
  5. PR 一旦经过 code review 无误后即可合并到 master
  6. master 一旦接收到合并请求,即可立即部署发布

github-flow-whole

GitHub Flow的代码开发工作流程如下:

  1. 创建特性分支:从主分支中创建一个新的特性分支,用于开发新功能或修复bug。
  2. 开发和测试:在特性分支上进行开发和测试,确保代码符合质量标准,并通过自动化测试。
  3. 发起合并请求:将特性分支合并到主分支中,发起一个合并请求(pull request),并邀请其他开发者进行代码审查和讨论。
  4. 代码审查:其他开发者对代码进行审查和讨论,提出意见和建议,并确保代码符合质量标准和最佳实践。
  5. 合并代码:在经过审查和讨论后,将特性分支合并到主分支中,并将代码部署到生产环境。
  6. 部署代码:在合并到主分支后,使用自动化部署工具将代码部署到生产环境。

Gitlab flow 模型

GitLab Flow是一个基于GitLab的分支模型和开发工作流程,旨在支持敏捷开发和持续交付。

GitLab 在 2014 年提出 11 条最佳实践,更多请点击这里,其相对 GitHub 增加了环境分支,且代码必须由上游master)向下游staging)发展,并且针对持续发布和版本发布都提出了相应的准则,下面是其大致流程图:

img

GitLab Flow的主要特点包括:

  1. 简单的分支模型:GitLab Flow使用一个简单的分支模型,包括一个主分支(通常命名为“master”或“production”)和一个开发分支(通常命名为“develop”或“staging”)。特性分支从开发分支创建,并在特性或错误修复完成并通过测试后合并回开发分支中。
  2. 持续集成和交付:GitLab Flow强调持续集成和交付(CI/CD),这意味着每次对代码的更改都会自动构建、测试和部署到测试环境或生产环境(如果测试通过)。
  3. 代码审查:GitLab Flow鼓励进行代码审查,这意味着每次对代码的更改都会由至少一个其他开发人员进行审查,以确保其符合质量标准并不会引入任何安全漏洞。
  4. 合并请求:GitLab Flow使用合并请求来管理将代码更改合并到主分支的过程。合并请求允许开发人员在将更改合并到主分支之前对其进行审查和讨论。
  5. 环境管理:GitLab Flow提供高级的环境管理功能,允许团队创建和管理不同的开发、测试、暂存和生产环境。

GitLab Flow提供了高级的环境管理功能,可以帮助团队更好地管理不同的开发、测试、暂存和生产环境。以下是使用GitLab Flow进行环境管理的一些方法:

  1. 创建不同的环境分支:在GitLab Flow中,可以为不同的环境创建分支。例如,可以创建一个名为“develop”的开发分支,一个名为“staging”的暂存分支,和一个名为“production”的生产分支。这些分支可以帮助团队更好地管理不同环境的代码,确保每个环境都有自己的代码版本。
  2. 配置环境变量:在GitLab中,可以为每个环境设置不同的环境变量。这些环境变量可以用于配置不同环境中的应用程序和服务,例如数据库连接字符串、API密钥等。通过设置正确的环境变量,可以确保应用程序在不同环境中正确运行。
  3. 自动化部署和测试:GitLab Flow支持自动化部署和测试,可以帮助团队更快地部署代码到不同环境中。可以使用GitLab的CI/CD管道来自动化测试和部署过程,并将代码推送到正确的环境分支中。
  4. 环境监控和报告:GitLab Flow还支持环境监控和报告功能,可以帮助团队更好地了解不同环境的运行状况和性能。可以使用GitLab的监控和报告工具来监视不同环境的性能指标、错误率等,并及时发现和解决问题。

GitLab Flow的分支模型如下:

  1. 主分支:主分支始终处于稳定状态,并用于生产环境。在GitLab Flow中,主分支通常是master分支或production分支。
  2. 特性分支:特性分支用于开发新功能或修复bug,并从主分支中创建。在GitLab Flow中,特性分支通常以feature/或fix/为前缀。
  3. 集成分支:集成分支用于将特性分支集成到主分支中,并进行测试和部署。在GitLab Flow中,集成分支通常是develop分支或staging分支。
  4. 发布分支:发布分支用于将特性分支和集成分支的代码发布到生产环境中。在GitLab Flow中,发布分支通常是release/为前缀的分支。

GitLab Flow的开发工作流程如下:

  1. 创建特性分支:从主分支中创建一个新的特性分支,用于开发新功能或修复bug。
  2. 开发和测试:在特性分支上进行开发和测试,确保代码符合质量标准,并通过自动化测试。
  3. 合并到集成分支:将特性分支合并到集成分支中,并进行集成测试和自动化部署。
  4. 发布到生产环境:将集成分支的代码发布到生产环境中,并进行最终测试和部署。
  5. 合并到主分支:在发布到生产环境后,将集成分支合并到主分支中,并将代码部署到生产环境。

GitLab Flow强调CI/CD集成和测试自动化,以确保代码质量和快速迭代。它还支持自动化部署和环境管理,以帮助开发人员更轻松地管理不同环境和部署代码。GitLab Flow是一个灵活和强大的开发工作流程,适用于各种类型的项目和团队。

GitLab Flow、Git Flow和GitHub Flow

GitLab Flow、Git Flow和GitHub Flow都是三种常见的基于Git的工作流程。下面是GitLab Flow与其他工作流程的主要区别:

  1. GitLab Flow与Git Flow的比较:
  • GitLab Flow比Git Flow更简单和更灵活。Git Flow有一个更复杂的分支模型,包含多个长期存在的分支,而GitLab Flow只使用几个主要分支和特性分支。

  • GitLab Flow强调持续集成和持续部署(CI/CD),鼓励频繁合并到主要分支。Git Flow更注重版本控制和发布管理。

  • GitLab Flow与GitLab内置的CI/CD管道更紧密地集成在一起,更容易自动化开发工作流程。

  1. GitLab Flow与GitHub Flow的比较:
  • GitLab Flow和GitHub Flow有许多相似之处,例如它们都以GitHub或GitLab作为中央仓库,使用特性分支进行开发。
  • GitLab Flow强调CI/CD集成和测试自动化,而GitHub Flow更注重代码审查和协作。
  • GitLab Flow还提供更高级的环境管理、部署和监控功能,更适合于大型、复杂的项目。

总体而言,GitLab Flow比Git Flow更简单和更灵活,强调CI/CD集成和自动化。与GitHub Flow相比,GitLab Flow提供更高级的环境管理和部署功能,更适合于大型、复杂的项目。选择哪种工作流程最终取决于项目和开发团队的具体需求和要求。

其他 flow

  • TrunkBased
  • OneFlow
  • AoneFlow

总结

目前公司代码部署在自建的 gitlab 上面,对于公司的项目,个人倾向于使用 git-flow 分支模型,并且使用 git-flow (AVH Edition) 来简化操作。

目前,我参与的大多数项目都是 java 项目并且使用 maven 进行构建。

在Maven项目中,可以使用Maven版本控制器来区分release版本和snapshot版本。

  • Release版本

    对于Git Flow中的release分支,通常用于为生产环境准备代码。

    在Maven项目中,可以使用Maven Release插件来自动化创建和发布release版本。

    mvn release:prepare
    mvn release:perform
    

    使用这些命令,Maven Release插件会自动更新项目版本号、创建tag、构建release版本,并发布到Maven仓库中。发布的版本号不包含 -SNAPSHOT 后缀。

    或者,使用 mvn versions

    mvn versions:set -DnewVersion=1.0.0-SNAPSHOT
    mvn versions:commit
    
  • Snapshot版本

    对于Git Flow中的feature和develop分支,通常用于开发和测试新功能或bug修复,这些分支使用snapshot版本。在Maven中,snapshot版本的版本号包含 -SNAPSHOT 后缀,表示当前版本是正在开发的版本。

对于这些项目,git-flow 操作步骤如下:

1、初始化

git flow init -d

2、开始 feature 分支

git flow feature start test

设置maven项目中版本为 snapshot版本。

mvn versions:set -DnewVersion=1.0.0-SNAPSHOT
mvn versions:commit

对于maven多模块项目,如果使用 revision 来统一定义版本号,则使用下面命令:

mvn versions:set-property -Dproperty=revision -DnewVersion=1.0.0-SNAPSHOT

3、本地在 feature 分支上完成一些开发之后,完成 feature 分支

git flow feature finish test

4、开始 release 分支

git flow release start 1.0.0

5、本地在 release 分支上完成一些开发之后,完成 feature 分支

设置maven项目中版本为 release 版本。

mvn versions:set -DnewVersion=1.0.0
mvn versions:commit

对于maven多模块项目,如果使用 revision 来统一定义版本号,则使用下面命令:

mvn versions:set-property -Dproperty=revision -DnewVersion=1.0.0

另外,对于多模块项目,需要在每个模块执行下面命令将 jar 推送到 maven 中央仓库:

mvn install -DskipTests

然后完成分支:

git flow release finish 1.0.0

以上。