Git 中的分支策略

Avatar of Tobias Günther
Tobias Günther

DigitalOcean 为您的旅程各个阶段提供云产品。 立即开始使用 $200 免费积分!

本文是“高级 Git”系列的一部分。 务必 关注我们在 Twitter 上注册我们的时事通讯 以了解下一篇文章!

几乎所有版本控制系统 (VCS) 都在某种程度上支持分支。 简而言之,分支 意味着您通过为您的工作创建新的独立容器来离开主开发线,并继续在那里工作。 这样,您就可以进行实验和尝试新事物,而不会弄乱生产代码库。 Git 用户知道 Git 的分支模型很特别,非常强大; 它是这个 VCS 最酷的功能之一。 它速度快且轻便,在分支之间来回切换与创建或删除它们一样快。 可以说 Git 鼓励使用大量分支和合并的工作流程。

Git 完全由您决定创建多少个分支以及合并它们的频率。 现在,如果您独自编码,您可以选择何时创建新分支以及想要保留多少个分支。 但是,当您在团队中工作时,情况就会发生变化。 Git 提供了工具,但您和您的团队有责任以最佳方式使用它!

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

高级 Git 系列

  1. 第 1 部分: 在 Git 中创建完美的提交
  2. 第 2 部分: Git 中的分支策略 (您在这里!)
  3. 第 3 部分: 通过拉取请求实现更好的协作
  4. 第 4 部分: 合并冲突
  5. 第 5 部分: 变基与合并
  6. 第 6 部分: 交互式变基
  7. 第 7 部分: 在 Git 中挑选提交
  8. 第 8 部分: 使用 Reflog 恢复丢失的提交

团队合作:写下约定

在我们探索构建发布和集成更改的不同方法之前,让我们谈谈约定。 如果您在团队中工作,您需要就项目的共同工作流程和分支策略达成一致。 最好将其写下来,以便所有团队成员都可以访问。

诚然,并非每个人都喜欢编写文档或指南,但将最佳实践记录在案不仅可以避免错误和冲突,还可以帮助入职新团队成员。 解释您的分支策略的文档将帮助他们了解您的工作方式以及您的团队如何处理软件发布。

以下是一些来自我们自己的文档的示例

  • master 代表当前公共发布分支
  • next 代表下一个公共发布分支(这样我们就可以在 master 上提交热修复,而不会引入不需要的更改)
  • 功能分支被分组在 feature/
  • WIP 分支被分组在 wip/ 下(这些分支可用于创建您个人 WIP 的“备份”)

不同的团队可能对这些事情有不同的看法(例如关于“wip”或“feature”组),这当然会反映在他们自己的文档中。

集成更改和构建发布

当您考虑如何在 Git 存储库中使用分支时,您可能应该首先考虑如何集成更改以及如何构建发布。 所有这些主题都紧密相连。 为了帮助您更好地了解您的选择,让我们看看两种不同的策略。 这些示例旨在说明频谱的极端,这就是为什么它们应该给您提供一些关于如何设计自己的分支工作流程的想法

  • 主线开发
  • 状态、发布和功能分支

第一个选项可以描述为“始终集成”,它基本上归结为:始终将您自己的工作与团队的工作集成。 在第二种策略中,您收集您的工作并发布其集合,即多种不同类型的分支进入阶段。 两种方法都有其优缺点,两种策略都适合某些团队,但不适合其他团队。 大多数开发团队的工作介于这两种极端之间。

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

主线开发

我之前说过,但这方法的座右铭是“始终集成”。 您只有一个分支,每个人都通过提交到主线来做出贡献

请记住,我们在为这个示例进行简化。 我怀疑现实世界中没有任何团队使用如此简单的分支结构。 但是,它确实有助于理解该模型的优缺点。

首先,您只有一个分支,这使得跟踪项目中的更改变得容易。 其次,提交必须相对较小:您不能在不断将事物集成到生产代码的环境中冒着大型臃肿提交的风险。 结果,您团队的测试和 QA 标准必须一流! 如果您没有高质量的测试环境,主线开发方法将不适合您。

状态、发布和功能分支

现在让我们看看相反的情况,以及如何使用多种不同类型的分支。 它们都有不同的工作:新功能和实验代码保存在它们自己的分支中,发布可以在它们自己的分支中进行计划和管理,甚至您开发流程中的各种状态也可以由分支表示

请记住,这一切都取决于您团队的需求和项目的具体要求。 虽然这种方法乍一看可能很复杂,但这都是练习和习惯问题。

现在,让我们更详细地探讨两种主要类型的分支:长期运行的分支和短暂的分支。

长期运行的分支

每个 Git 存储库都包含至少一个长期运行的分支,通常称为mastermain。 当然,您的团队可能决定在一个项目中拥有其他长期运行的分支,例如类似developproductionstaging这样的分支。 所有这些分支都有一个共同点:它们在项目的整个生命周期中都存在。

mastermain这样的主线分支是长期运行分支的一个例子。 此外,还有一些所谓的集成分支,例如developstaging。 这些分支通常代表项目发布或部署过程中的状态。 如果您的代码在其开发生命周期中经历了不同的状态——例如从开发到暂存到生产——那么在您的分支中也反映这种结构是有意义的。

关于长期运行分支的最后一点:大多数团队都有一个规则,例如“不要直接提交到长期运行的分支”。 相反,提交通常通过合并或变基进行集成。 这种约定的主要原因有两个

  • 质量: 不应将未经测试或未经审查的代码添加到生产环境中。
  • 发布捆绑和调度: 您可能希望分批发布新代码,甚至提前安排发布。

接下来:短暂的分支,通常出于特定目的而创建,并在代码集成后删除。

短暂的分支

与长期分支不同,短期分支是为临时目的创建的。一旦它们完成了任务,代码被整合到主线(或另一个长期分支)中,它们就会被删除。创建短期分支有很多不同的原因,例如开始开发一个新的实验性功能,修复一个错误,重构代码等等。

通常,短期分支基于一个长期分支。假设您开始开发软件的新功能。您可以将新功能基于您长期运行的 *main* 分支。在几次提交和一些测试之后,您决定工作完成了。新功能可以整合到 *main* 分支中,并且在合并或变基后,功能分支可以被删除。

在本文的最后一部分,让我们来看看两种流行的分支策略:Git Flow 和 GitHub Flow。虽然您和您的团队可能会决定使用完全不同的策略,但您可以将它们作为您自己的分支策略的灵感来源。

Git Flow

一种众所周知的分支策略称为 Git Flow。*main* 分支始终反映当前的生产状态。有一个第二个长期运行的分支,通常称为 *develop*。所有功能分支都从这里开始,并将合并到 *develop* 中。此外,它也是新发布的起点:开发人员打开一个新的 *release* 分支,在该分支上工作,测试它,并在这样的发布分支上提交他们的错误修复。一旦一切都正常工作,并且您确信它已准备好投入生产,您就可以将其合并回 *main*。作为最后一步,您在 *main* 上的发布提交添加一个标签,并删除 *release* 分支。

Git Flow 非常适合像(桌面)应用程序或库这样的打包软件,但对于网站项目来说似乎有点过分。在这里,主分支和发布分支之间的差异通常不足以从这种区分中获益。

如果您使用的是像 Tower 这样的 Git 桌面 GUI,您将找到界面中的可能操作,并且不必记忆任何新命令。

Git Flow offers a couple of predefined actions: a desktop GUI like Tower can save you from learning these new commands by heart.

GitHub Flow

如果您和您的团队遵循持续交付方法,并且拥有短的生产周期和频繁的发布,我建议您查看 GitHub Flow

它非常精简和简单:只有一个长期运行的分支,默认的 *main* 分支。您正在积极开发的任何内容都有其自己的独立分支。无论它是功能、错误修复还是重构,都没有关系。

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

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

如果您想更深入地了解高级 Git 工具,请随时查看我的(免费!)“高级 Git 工具包”:它是关于分支策略、交互式变基、Reflog、子模块等主题的短视频集合。

高级 Git 系列

  1. 第 1 部分: 在 Git 中创建完美的提交
  2. 第 2 部分: Git 中的分支策略 (您在这里!)
  3. 第 3 部分: 通过拉取请求实现更好的协作
  4. 第 4 部分: 合并冲突
  5. 第 5 部分: 变基与合并
  6. 第 6 部分: 交互式变基
  7. 第 7 部分: 在 Git 中挑选提交
  8. 第 8 部分: 使用 Reflog 恢复丢失的提交