分支策略
你组织和合并 Git 分支的方式称为分支策略。 对于许多团队来说,最简单的方法是合理且有效的:
- 在功能分支中进行更改。
- 将功能分支直接合并到
main。
但是,如果你的团队有复杂的需求(如测试和合规要求), 你可能需要考虑不同的分支策略。
我们希望为一些更常见的策略去神秘化。 不是每个团队都有 Git(或版本控制)专家。如果你知道 你的团队正在使用 Git 技能的极限,这份信息就是为你准备的。
当你使用 GitLab 替代多个不同的工具时,你做出的关于 Git 分支策略的决定就很重要。通过仔细规划,你可以建立清晰的 连接:
- 你收到的初始错误报告。
- 你的团队为修复这些错误所做的提交。
- 将这些修复回退到其他版本或客户的过程。
- 使你的修复对用户可用的部署。
谨慎的选择能帮助你充分利用 GitLab 中的单一数据存储。
我是否需要更复杂的 Git 分支策略?
如果你遇到以下情况,你可能已经超出了当前 Git 分支策略的能力范围:
- 你使用持续交付。
- 你有大量的自动化测试。
- 你必须为一个客户修复关键错误,而不影响其他客户。
- 你维护产品的多个历史版本。
- 你的产品没有单一的生产分支,因为它支持多个操作系统或平台。
- 你的每个版本都有不同的部署或认证要求。
不要实施比产品需求更复杂的策略。
何时将项目拆分为多个仓库
你应该维护一个具有复杂分支结构的 Git 仓库,还是将项目 拆分为多个仓库?没有单一的正确答案。这取决于你拥有的人员 和专业知识来支持。
GitLab 提供的自动化功能假设你的仓库是针对单一产品的,尽管该产品 可能包含多个版本。要确定你应该拥有多个仓库,还是 一个复杂的单一仓库,请考虑以下问题:
- 是同一个产品吗?
- 所有元素都使用相同的构建过程吗?
- 底层代码是相似还是相同?
无论你选择什么(无论是复杂的单一仓库,还是一组较小的仓库), 你都应该期望花费工程时间进行维护。确定你准备好进行的 工程工作类型:
- 如果你在一个仓库中维护多个产品的代码,计划以后进行 定制化工作,以使用 GitLab 的所有功能。
- 跨多个仓库合并工作比在同一仓库中跨分支合并更复杂。 计划工程时间来构建自定义发布流程并管理代码 在仓库间的流动。
如果你的组织使用大型单体仓库或超大型仓库,GitLab 的 专业服务 团队可以帮助你构建一个 满足你需求的自定义分支解决方案。
主要的分支策略类型
分支和代码管理策略取决于你的产品需求。 没有预先存在的策略能涵盖所有情况,但我们已经识别出一些主要类别:
Web 服务
此策略遵循标准的 Git 实践。main 分支是你的生产分支,
这对于单个 Web 服务来说很棒:有一个权威的生产版本,
并且不支持以前的修订版本。
对于此配置,git-flow
可能适合你。它是标准化的,你不需要维护任何东西。
在此示例中,feature-1 直接从 main 分支出来。完成后,feature-1 直接合并回
main。这个合并提交用方框突出显示。更长期的分支,如
feature-2,可能会在开发过程中定期合并来自 main 的最新更新。
完成后,feature-2 合并到 main,并发布 1.1 版本:
%%{init: { 'gitGraph': {'mainBranchOrder':1}} }%%
gitGraph
commit tag: "1.0" id: "release v1.0"
branch "feature-1"
commit id: "start feature-1"
checkout main
commit id: "start feature-2"
branch "feature-2" order: 3
checkout feature-1
commit id: "refine feature-1"
checkout main
merge feature-1 type: HIGHLIGHT id: "merge feature-1 into main"
checkout feature-2
commit id: "build feature 2"
merge main type: HIGHLIGHT id: "merge main into feature-2"
commit
checkout main
merge feature-2 tag: "1.1" type: HIGHLIGHT id: "release v1.1"
长期存在的发布分支
如果你的产品有必须与 main 长期保持分离的分支,这种分支策略是合适的。一些示例包括:
- 同一软件包的多个生产版本。例如:当前版本和 旧版本。当前版本接收功能更新和热修复,而以前的版本 只接收热修复和安全更新。
- 当前生产版本和长期存在的测试版本。当你需要处理一个主要的 软件依赖项(如软件开发工具包,或 SDK)引入破坏性更改时, 你可能需要这种方法。当前生产版本接收功能更新和热修复。 测试版本接收这些功能更新和热修复,同时你的团队也构建了对即将到来的 SDK 更改的支持。
如果你打算锁定一个长期存在的分支,定义并强制执行你的热修复过程至关重要。 如果未定义且未强制执行,每个更改都将成为热修复。
在此示例中,2.0 分支是从 main 上 1.0 版本的提交创建的。
功能分支从 2.0 分支分出,并合并回 2.0。同时,任何热修复
分支都基于 main 的最新版本(1.0),并合并回 main 作为
版本 1.1。然后 2.0 分支拉入版本 1.1 的更改,并将它们
作为 2.0 开发的一部分合并。在添加另一个功能(feature-2)后,
2.0 分支准备好投入生产。它合并到 main,并发布 2.0 版本:
%%{init: { 'gitGraph': {'mainBranchOrder':2}} }%%
gitGraph
commit tag: "1.0"
branch hotfix order: 1
checkout main
branch "2.0" order: 3
commit
checkout hotfix
commit id: "security bug"
commit id: "performance bug"
checkout "2.0"
branch feature-1 order: 4
commit id: "create feature 1"
checkout main
commit id: " "
checkout 2.0
merge feature-1 id:"merge feature-1" tag: "2.0 RC 1"
checkout main
merge hotfix tag: "1.1" type: HIGHLIGHT
checkout 2.0
merge main tag: "2.0 RC 2" type: HIGHLIGHT
branch feature-2 order: 5
commit id: "create feature 2"
commit id: "refine feature 2"
checkout 2.0
merge feature-2 id: "merge feature-2" tag: "2.0 RC 3"
checkout main
merge 2.0 tag: "2.0" type: HIGHLIGHT
从 SVN 分支策略迁移
从 SVN 迁移到 Git 的遗留项目应该审查其分支方法。 Git 中一些以 SVN 为中心的分支方法可能会阻止你充分利用 GitLab。需要重新审视的一些工作流程:
- 你从
main创建一个长期存在的分支(如1.0),然后锁定1.0分支以阻止任何 不是预先批准的热修复的更改。- Git 处理合并冲突的能力比 SVN 更好。
- 避免创建长期存在的分支,除非你有合同义务 使用它们。虽然 Git 能很好地处理冲突,但长期存在的分支需要你 花费时间将修复合并到多个分支。
- 你使用分支是因为你的产品不支持功能标志。
每个环境一个分支
这种分支策略对于拥有多个相互依赖服务且由不同团队构建的组织很常见。 它通常与瀑布模型或 V 模型开发流程一起使用。
在此示例中,标记为 v1.1 RC1 的提交被确定为版本 1.1 的候选发布。
功能继续从 main 分支并合并回 main,而候选发布提交在
test 和 UAT 环境中进行测试。这个过程对于每个考虑发布的提交都会重复:
gitGraph
commit id: "start feature"
branch feature-1
checkout main
commit tag: "v1.1 RC1" id: "start testing"
branch test
checkout feature-1
commit id: "develop feature"
commit id: "refine feature"
checkout test
commit id: " " tag: "v1.1 RC1"
branch UAT
checkout UAT
commit tag: "v1.1"
checkout main
merge feature-1 id: "merge feature-1"
commit