Gitflow

Gitflow 由 Vincent Driessen 在 2010 提出。Gitflow 有着严格的流程:只有 2 个主干分支,Master 和 Develop 分支:Master 分支上只有稳定的生产版本,Develop 分支用于集成。而其他还有三类辅助性质的分支:Feature 分支用于开发人员各自开发;Release 用于代码合并和集成;Hotfix 用于产品版本代码的紧急修复。

gitflow-all.png

主要分支 The main branches

  • Master 分支
  • Develop 分支

gitflow-main.png

当 Develop 分支中的源代码达到稳定状态并准备发布时,所有的修改应该以某种方式合并回 Master 中,然后打 tag。具体如何做,在后面进一步讨论。

因此,每次当变化被合并回主版本时,根据定义,就是一个新的生产版本。在这一点上往往非常严格,所以理论上,我们可以使用 Git 钩子脚本,在每次主版有提交时,自动构建并将软件发布到生产服务器上。

次要(辅助)分支 Supporting branches

  • Feature branches
  • Release branches
  • Hotfix branches

Feature 分支

  • develop 分支拉出来
  • 完成开发完,合并回 develop
  • 分支命名比较随意,语义化即可 release-*, or hotfix-*

Release 分支

Release 分支支持新生产版本的准备工作,允许进行小的错误修复,并为发行版准备元数据(版本号、构建日期等)

通过在 Release 分支上做这些工作,Develop 分支就可以开发下一个大版本的功能。

  • develop 分支拉出来
  • 完成开发完,合并回 developmaster
  • 分支命名应该为: release-*

Hotfix 分支

生产版本有存在 bug 的时候,从 Master 上建立 Hotfix 分支,团队成员(在 Develop 分支上)的工作可以继续,而另一个人则在准备快速的生产修复。

  • master 分支拉出来
  • 完成开发完,合并回 developmaster
  • 分支命名应该为: hotfix-*

gitflow-hotfix.png

问题:

  • Hotfix 分支和 Release 分支引入了复杂性,例如 Release branches 和 Hotfix branches 都需要同时 merge 到 Master 和 Develop,容易忘记(对比我们的 Release 分支)。
  • 在实际的需求中,它比想象的更复杂,以至于开发了一个大的脚本来帮助严格执行这个流程。https://github.com/nvie/gitflow
  • 分支周期很长,合并困难,影响持续集成。
  • 持续交付降低甚至消除了对 Hotfix 和 Release 分支的需求。

ThoughtWorks 也一直在抨击 GitFlow 模型:

作者在最近,在这篇文章上加上了 note(具体见博客):

Git 开发的最流行的软件类型也更多地转向了 Web 应用。网络应用通常是持续交付的,而不是回滚的,而且你不必支持软件的多个版本在运行。这不是我 10 年前写博文时想到的那一类软件。如果你的团队正在做软件的持续交付,我会建议采用更简单的工作流程(比如 GitHub flow),而不是试图将 git-flow 塞进你的团队。

GithubFlow

发布于 < a href="https://scottchacon.com/2011/08/31/github-flow.html">https://scottchacon.com/2011/08/31/github-flow.html 。GitHub Flow 推荐只有一个主分支 master,团队成员们的分支代码通过 Pull Request 来合并到 master 上。

github-flow.png

原则(Copy from https://scottchacon.com/2011/08/31/github-flow.html ):

  • Anything in the master branch is deployable
  • To work on something new, create a descriptively named branch off of master (ie: new-oauth2-scopes)
  • Commit to that branch locally and regularly push your work to the same named branch on the server
  • When you need feedback (这个如何做到) or help, or you think the branch is ready for merging, open a pull request
  • After someone else has reviewed and signed off on the feature, you can merge it into master
  • Once it is merged and pushed to ‘master’, you can and should deploy immediately

这里需要注意第六条后面的说明:

Finally, your work is done and merged into the master branch. This means that even if you don’t deploy it now, people will base new work off of it and the next deploy, which will likely happen in a few hours, will push it out. So since you really don’t want someone else to push something that you wrote that breaks things, people tend to make sure that it really is stable when it’s merged and people also tend to push their own changes.

最后,你的工作完成了,并合并到主分支中。这意味着即使你现在不部署它,人们也会以它为基础进行新的工作,而下一次部署,很可能会在几个小时后进行,会把它推送出去。所以,由于你真的不希望别人推送你写的东西破坏了一些东西,所以其他人在合并的时候往往会确保它真的是稳定的,其他人也往往会(介于这个 PR)推送自己的修改。

// 这里可以看出,Github Flow 针对的(理想)场景是每天可能发布数次。

步骤(Copy from Github):

Create a branch from the repository.Create, edit, rename, move, or delete files.Send a pull request from your branch with your proposed changes to kick off a discussion.Make changes on your branch as needed. Your pull request will update automatically.Merge the pull request once the branch is ready to be merged.Tidy up your branches using the delete button in the pull request or on the branches page.

可以看一下官方的介绍:https://guides.github.com/introduction/flow/ 带一点动画

优势:

  • 干净整洁容易理解。
  • 真正意义上的控制代码的合并。
  • 及时的发现代码中存在的问题。
  • 通过 issue 进行问题追踪。可以通过 tag 对问题进行分类。
  • 分支的周期很短。

存在的问题:

  • 没有解决不同环境的问题,没有解决开发节奏和交付节奏不一致的问题。
  • 不是很适合 web service。
  • 基础设施要求高。
  • 到达理想状态很遥远。

GitLab Flow

GitLab flow 是 GitLab 官方推荐的分支管理策略,他吸收了 Git flow 和 Github flow 的优点。Gitlab flow 的最大原则叫做 "上游优先"(upsteam first),即只存在一个主分支 master,它是所有其他分支的 "上游"。只有上游分支采纳的代码变化,才能应用到其他(出了 feature 分支以外)分支。

https://docs.gitlab.com/ee/topics/gitlab_flow.html#git-flow-and-its-problems

延迟发布 - Production 分支

控制发布时间

gitlab-flow-1.png

Environment 分支

解决不同环境的问题

gitlab-flow-2.png

Release 分支

如果代码不是部署到某个环境,而是需要对外发布,则可以使用 release 分支。

gitlab-flow-3.png

我的理解是这三种分支策略可以视情况选择。

问题:

  • Hotfix 怎么办 - 官方文档没有说明

Trunk-Based Development

创作者:Paul Hammant

https://paulhammant.com/2013/04/05/what-is-trunk-based-development/

trunk 是 SVN 中主干分支的名称,对应 Git 中则是 < code>master 分支。

trunk-base.png

如果需要发布,可以基于主干发布(利用 tag)作为发布的版本,如果满足不了需求,则从主干分支创建发布分支。

如果需要修复 bug,按照主干开发的最佳实践应该是在主干分支上重现 bug,并在主干分支修复和测试,通过持续集成再 cherry-pick 到发布分支,等待发布分支的持续集成再一步验证,在进入生产环境。

适合与不适合

  • 比较需要 Senior developers,不太适合团队成员大部分都是 Junior developers

Q&A:

和 Github Flow 的不同:

  1. 主干开发仍有细微差别主要区别在从何进行发布。Github flow 存在一点小问题:可以从分支直接发布,但是这个分支上可能落后了几个 commit,导致一些功能缺失

trunk-base-merge.png

trunk-base-release.png

和 Gitlab Flow 的不同

  1. 分支策略更为严格?

feature 没有开发完,要 release 怎么办:

  • feature toggle
  • Branch by Abstraction

问题:

  • 开源项目采用什么策略【还没看】
    • Github flow 更适合开源项目
  • 各种分支策略在团队规模不同上的差别
  • 我们平时关注的是 Web 开发,其他的类型的开发采用的策略是什么,如:
    • Data 项目
    • 移动开发
    • lib
    • 产品的开发
  • 发展的趋势来看,我们总体在关注哪些方面
    • 在实际应用中的复杂度 ➡️简单
    • 分支的生命周期 long ➡️short-lived

参考文章: