写点什么

Git 进阶系列 | 2. Git 中的分支策略

作者:俞凡
  • 2022 年 5 月 02 日
  • 本文字数:3141 字

    阅读完需:约 10 分钟

Git 是最流行的代码版本控制系统,这一系列文章介绍了一些 Git 的高阶使用方式,从而帮助我们可以更好的利用 Git 的能力。本系列一共 8 篇文章,这是第 2 篇。原文:Branching Strategies in Git[1]


几乎所有的版本控制系统(VCS)都有某种类型的分支支持。简而言之,分支意味着可以创建一个新的、独立的容器而离开主开发线,并继续在那里工作。通过这种方式,可以在不破坏生产代码库的情况下进行试验和尝试。Git 用户知道 Git 的分支模型非常特殊,而且非常强大,这是 Git 最酷的功能之一。Git 的分支模型快速且轻量,在分支之间来回切换的速度与创建或删除分支一样快。可以说 Git 鼓励使用大量分支和合并的工作流。


Git 把创建多少分支以及合并的频率完全交给了开发者决定。如果你独自编写代码,可以自由选择什么时候创建新分支,以及保留多少个分支。但当我们在团队中工作时,情况就不同了。Git 提供工具,但是团队需要负责以最佳方式使用这一工具!


本文将讨论分支策略和不同类型的 Git 分支,还会介绍两种常见的分支工作流: Git Flow 和 GitHub Flow。


Git 进阶系列:

  1. 创建完美的提交

  2. Git 中的分支策略(本文)

  3. 基于 Pull Request 实现更好的协作

  4. 合并冲突

  5. Rebase vs Merge

  6. 交互式 Rebase

  7. Git 中的 Cherry-pick 提交

  8. 用 Reflog 恢复丢失的提交

团队合作: 制定规则


在探索构建发布和集成变更的不同方法之前,先来讨论一下规则。如果在团队中工作,需要对项目的通用工作流和分支策略达成一致,最好将其写下来,让所有团队成员都能看到。


诚然,并不是每个人都喜欢编写文档或指导方针,但将最佳实践记录在案不仅可以避免错误和冲突,还有助于培训新团队成员。解释分支策略的文档将帮助他们理解团队是如何工作的,以及如何处理软件版本。


以下是我们自己文档中的一些例子:

  • master代表当前的公开发布分支

  • next表示下一个公开发布分支(这样我们就可以在 master 上提交修补程序而不会引入不必要的更改)

  • 特性分支被分组在feature/

  • WIP 分支被分组在wip/下(可以用来创建个人 WIP 的“备份”)


不同团队可能对这些规则有不同看法(例如“wip”或“feature”组),这肯定会反映在他们自己的文档中。

集成变更和结构化发布


当我们考虑如何在 Git 仓库中使用分支时,应该从考虑如何集成变更和如何构建发布开始。所有这些话题都是紧密相连的,为了更好的理解不同的选择,我们来看下两种不同的策略。下面的例子是为了说明极端情况会怎么样,从而帮助你思考如何设计自己的分支工作流:


  • 主线开发

  • 状态分支、发布分支和特性分支


第一个选择可以被描述为“始终集成”,基本上可以归结为: 始终将自己的工作与团队的工作集成在一起。在第二种策略中,收集自己的工作并发布,即多个不同类型的分支进入预发阶段。两种方法各有利弊,两种策略都适用于某些团队,但不适用于另一些团队,大多数开发团队在这两个极端之间工作。


我们从主线开发开始解释这个策略是如何工作的。

主线开发


之前提到过,这种方法的座右铭是“总是集成”。只有一个单独的分支,每个人都在主线上开发:



记住,这是一个简化的例子,我怀疑在现实世界中是否有任何团队能够使用如此简单的分支结构。然而,理解这个模型的优点和缺点确实有帮助。


首先,只有一个分支,因此很容易跟踪项目中的变化。其次,提交必须相对较小: 在不断集成到生产代码的环境中,不能冒险进行大而臃肿的提交。因此,团队的测试和 QA 标准必须是一流的!如果没有一个高质量的测试环境,主线开发方法就不适合。

状态分支、发布分支和特性分支


下面看看另一种情况,如何使用多个不同类型的分支。每个分支都有不同的工作: 新特性和实验代码保存在自己的分支中,发布可以在自己的分支中规划和管理,甚至开发流程中的各种状态也可以用分支来表示:



记住,这完全取决于团队和项目的需求。虽然这种方法一开始可能看起来很复杂,但完全是一个练习和习惯的问题。


现在,让我们更详细地探讨两种主要的分支类型: 长期分支(long-running branches)和短期分支(short-lived branches)。

长期分支


每个 Git 仓库至少包含一个长期分支,通常称为mastermain。当然,团队可能会决定在项目中使用其他长期分支,例如类似于开发(develop)、生产(production)或预发(staging)分支。所有这些分支都有一个共同点: 存在于整个项目生命周期中。



mastermain这样的主线分支是长期分支的一个例子。此外,还有所谓的集成分支,如开发或预发。这些分支通常代表项目发布或部署过程中的状态。如果代码在开发生命周期中经历了不同的状态(例如,从开发阶段到预发阶段再到生产阶段),在分支中的这个镜像结构也是有意义的。


关于长期分支的最后一点: 大多数团队都有一个类似于“不要直接向长期分支提交内容”的规则,通常通过 merge 或 rebase 来集成。制定这项规则有两个主要原因:


  • 质量: 不应将未经测试或评审的代码发布到生产环境中。

  • 捆绑发布和调度: 可能希望分批发布新代码,甚至提前安排发布。


接下来是短期分支,通常为特定目的而创建,然后在代码集成后删除。

短期分支


与长期分支相反,短期分支是为临时目的而创建的,一旦它们完成了职责并且代码被集成到主线(或另一个长期分支)中,就会被删除。有许多不同的原因需要创建短期分支,例如致力于新的实验性特性,修复 bug,重构代码,等等。


短期分支通常基于长期分支创建。假设我们开始有一个新特性的开发,可以基于长期的主分支创建新特性分支。在若干次提交和测试之后,工作完成,新特性可以集成到主分支中,并且 merge 或 rebase 之后,可以删除特性分支。


两种流行的分支策略


最后我们看一下两种流行的分支策略: Git Flow 和 GitHub Flow。虽然不同的团队可能会决定完全不同的分支策略,但这两种流行的策略可以作为团队分支策略的灵感来源。

Git Flow


Git Flow[2]是一个著名的分支策略,其中main分支总是反映当前的生产状态,此外还有第二个长期分支,通常称为develop。所有特性分支都从这里创建,并将合并到develop中。而且,该分支是新发布的起点: 开发人员创建一个新的release分支,在上面工作、测试、提交 bug 修复。一旦一切正常,并且确信已经准备好投入生产,就将它合并回main。作为最后一步,在main上为发布添加一个标签,并删除release分支。


Git Flow 对于可打包的软件(桌面)应用程序或库来说工作得很好,但对于网站项目来说似乎有点过头了。在这类项目里,main分支和release分支之间通常区别不大,分不同的分支没有特别大的好处。

如果使用的是像 Tower 这样的 Git 桌面 GUI,可以在界面中找到可能的操作,不需要记住任何新命令:

GitHub Flow


如果团队遵循短生产周期和频繁发布的持续交付方式,建议看看 GitHub Flow[3]


这种方式非常精益和简单: 有一个长期分支,即默认的main分支,任何正在做的工作都有自己独立的分支,无所谓是新特性、bug 修复还是重构。


“最好”的 Git 分支策略是什么?


如果问 10 个不同的团队他们是如何使用 Git 分支的,可能会得到 10 个不同的答案。没有所谓的“最佳”分支策略,也没有每个人都应该采用的完美工作流。为了找到最适合团队的模型,应该坐下来分析所做的项目,讨论发布策略,然后决定一个分支工作流,从而以最好的方式支持我们的项目。


如果想更深入了解高级 Git 工具,可以免费查看“Advanced Git Kit[3]”: 这是关于分支策略、交互式 Rebase、Reflog、子模块等主题的短视频集合。


References:

[1] Branching Strategies in Git: https://css-tricks.com/branching-strategies-in-git/

[2] A Successful Git Branching Model: http://nvie.com/posts/a-successful-git-branching-model/

[3] GitHub Flow: https://guides.github.com/introduction/flow/


你好,我是俞凡,在 Motorola 做过研发,现在在 Mavenir 做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI 等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。

微信公众号:DeepNoMind

发布于: 刚刚阅读数: 2
用户头像

俞凡

关注

公众号:DeepNoMind 2017.10.18 加入

俞凡,Mavenir Systems研发总监,关注高可用架构、高性能服务、5G、人工智能、区块链、DevOps、Agile等。公众号:DeepNoMind

评论

发布
暂无评论
Git进阶系列 | 2. Git中的分支策略_git_俞凡_InfoQ写作社区