Git 分支管理策略:从日常开发到稳定发布

Git 分支管理策略:从日常开发到稳定发布

用AI写的, 用于参考

TLDR (Too Long; Didn't Read):

  • 核心原则:为每个新功能或 Bug 修复都创建一个新的、短生命周期的分支。 这能隔离工作、方便代码审查、保持主分支干净。完成后合并回主开发分支 (如 developmain),然后立即删除这个特性/Bug 分支
  • 长期分支 (如 main, develop, staging) 用于管理不同环境和发布阶段的代码状态。 main 通常是生产代码,develop 是集成开发代码,staging 是预生产测试代码。
  • 这两套分支策略是互补的:日常在短生命周期分支上开发,然后通过流程将代码合并到相应的长生命周期分支,最终部署到生产。
  • 关键操作
    git checkout -b feature/name 创建分支;
    git add ., git commit 提交;
    git merge --no-ff feature/name 合并分支 (推荐保留合并历史);
    git branch -d feature/namegit push origin --delete feature/name 删除分支。

核心原则:为每个任务创建独立分支(短生命周期分支)

无论项目大小,也无论开发者数量,为每一个独立的开发任务(如新功能、Bug 修复、代码重构、文档更新等)创建一个专门的分支都是最佳实践。

为什么这样做?

  1. 隔离性:每个任务在独立的环境中开发,不会与其他正在进行的工作互相干扰。如果一个特性开发遇到问题,不会影响主干代码。
  2. 清晰的提交历史:通过合并(尤其是 --no-ff)特性分支,可以将一组相关的提交聚合为一个逻辑单元,使得历史记录更易于理解和追溯。
  3. 代码审查 (Code Review):基于分支的 Pull Requests (PR) 或 Merge Requests (MR) 是进行代码审查的标准方式,方便团队成员针对特定改动进行讨论和反馈。
  4. 并行开发:团队成员可以同时在不同的特性分支上工作,互不阻塞。
  5. 易于放弃和回滚:如果某个特性不再需要或方向错误,可以直接删除该分支,对主干代码没有影响。
  6. 上下文切换:可以轻松地在不同任务之间切换,例如暂停一个特性开发去修复一个紧急 Bug。

典型工作流与命令

假设我们的主开发分支是 develop (或者 main 如果是更简单的流程)。

  1. 从基础分支创建新分支

    # 切换到基础分支并确保它是最新的
    git checkout develop
    git pull origin develop
    
    # 为新特性 "user-authentication" 创建并切换到新分支
    git checkout -b feature/user-authentication

    推荐命名规范feature/description, bugfix/issue-id-description, hotfix/description, chore/task-description

  2. 在新分支上开发和提交

    # ...进行代码修改...
    git add .
    git commit -m "Implement user login endpoint"
    
    # ...继续开发和提交...
    git commit -m "Add password hashing for user-authentication"
  3. 推送分支到远程 (可选但推荐)

    git push -u origin feature/user-authentication

    这有助于备份,并允许其他人看到你的进展或协作,也是创建 PR/MR 的前提。

  4. 创建 Pull Request / Merge Request
    在 Git 托管平台 (GitHub, GitLab, Bitbucket) 上,从 feature/user-authenticationdevelop 分支发起 PR/MR。

  5. 代码审查与合并
    PR/MR 通过审查后,通过平台界面合并,或者在本地合并:

    # 切换回目标分支并更新
    git checkout develop
    git pull origin develop
    
    # 合并特性分支 (推荐 --no-ff 保留合并信息)
    git merge --no-ff feature/user-authentication
    
    # 推送合并后的 develop 分支
    git push origin develop
  6. 删除已合并的分支 (非常重要!)

    # 删除本地分支
    git branch -d feature/user-authentication
    
    # 删除远程分支
    git push origin --delete feature/user-authentication

    许多 Git 平台在合并 PR/MR 后会自动提供删除源分支的选项。

环境驱动的长生命周期分支

除了为具体任务创建的短生命周期分支外,项目中通常还会维护一些长期存在的分支,它们代表了代码在不同环境或不同阶段的状态。

常见环境分支及其用途

  1. main (或 master)

    • 用途:通常代表生产环境就绪 (Production-Ready) 的代码。这个分支应该永远是稳定的、可部署的。
    • 合并来源:通常从 release 分支或经过充分测试的 develop (或 staging) 分支合并而来。
    • 重要性:直接部署到生产环境的代码来源,只接受经过严格测试和审查的代码。
  2. develop

    • 用途:作为主要开发集成 (Integration) 分支。所有已完成的 feature 分支通常会合并到这里。它代表了下一个版本中包含的所有新功能和修复。
    • 稳定性:相对 main 来说,develop 可能没那么稳定,但应该保持可编译和基本可运行状态,供日常测试和QA。
  3. staging (或 pre-production, uat)

    • 用途:用于用户验收测试 (UAT) 或预生产环境部署。这个分支的代码应该尽可能地接近生产环境。
    • 合并来源:通常从 develop 分支中某个稳定的点,或者从 release 分支合并而来。
    • 部署:此分支的代码会被部署到预生产服务器供测试人员或客户进行最终验证。
  4. production (可选)

    • 用途:有些团队会使用一个独立的 production 分支,严格映射当前生产环境部署的确切代码版本,通常通过标签指向。main 则可能代表“最新的稳定版”。在许多流程中,main 本身就扮演了生产分支的角色。
  5. 特殊用途的长/中生命周期分支

    • release/* (例如 release/v1.2.0):当 develop 分支达到一个准备发布的里程碑时,可以从 develop 创建一个 release 分支。此分支用于发布前的最后准备工作,如少量 Bug 修复、版本号更新、文档生成等。不允许再合入大的新功能。测试通过后,release 分支会合并到 main (打上版本标签) 和 develop (确保 develop 也包含这些修复)。
    • hotfix/* (例如 hotfix/critical-login-bug):当生产环境 (main) 出现紧急 Bug 需要立即修复时,从 main (或对应的生产标签) 创建 hotfix 分支。修复完成后,合并回 main (并打上新的紧急修复版本标签) 和 develop (以及活跃的 release 分支,如果存在)。

长生命周期分支的交互

简单的分支交互图 (概念 - Gitflow 模型)
(上图为经典 Gitflow 模型,实际可根据团队需求简化)

  • Feature 分支从 develop 拉出,完成后合并回 develop
  • develop 准备发布时,创建 release 分支。
  • release 分支完成后,合并到 maindevelop
  • hotfix 分支从 main 拉出,完成后合并回 maindevelop

结合两种模式:推荐的实践流程

对于大多数项目,推荐将以上两种模式结合起来:

  1. 日常开发:所有新功能和非紧急 Bug 修复都在从 develop (或 main,如果流程简化) 拉出的短生命周期分支 (feature/*, bugfix/*) 上进行。完成后通过 PR/MR 合并回 develop (或 main),然后删除这些短生命周期分支。

  2. 集成与测试develop 分支作为所有已完成特性的集成点,可以部署到开发或测试环境进行持续集成和测试。

  3. 发布准备

    • 简单流程:当 develop 分支被认为稳定并通过QA后,可以直接将其合并到 main,然后从 main 打标签并部署到 stagingproduction
    • Gitflow 流程:从 develop 创建 release/* 分支。在此分支上进行最终测试和微小修复。然后将 release/* 分支合并到 main (打标签) 和 develop
  4. 部署

    • main 分支的某个标签(或 release/* 分支)部署到 staging 环境进行 UAT。
    • UAT 通过后,将同一个标签/代码部署到 production 环境。
  5. 紧急修复 (Hotfix)

    • main (或生产环境对应的标签) 创建 hotfix/* 分支。
    • 修复、测试、合并回 main (打新标签),并同时合并回 develop (以及任何活跃的 release 分支)。
    • 部署新的 main 标签到生产环境。
    • 删除 hotfix/* 分支。

综合命令示例 (简化流程,以 main 为主干,develop 为集成)

1. 开始新功能 new-feature

git checkout develop
git pull origin develop
git checkout -b feature/new-feature develop
# ... 开发 ...
git add .
git commit -m "Add new-feature logic"
git push -u origin feature/new-feature
# ... 创建PR,审查,合并到 develop ...
# ... 在平台上或本地删除 feature/new-feature ...

2. 准备发布 (从 develop 到 main)

假设 develop 已经稳定,准备合并到 main

git checkout main
git pull origin main
git merge --no-ff develop -m "Merge develop for release v1.0.0" # 或通过PR
git tag v1.0.0
git push origin main
git push origin v1.0.0

3. 紧急修复生产 Bug critical-bug

从 main 拉取 hotfix 分支

git checkout main
git pull origin main # 确保基于最新的生产代码
git checkout -b hotfix/critical-bug main # 或者从某个生产标签 git checkout -b hotfix/critical-bug v1.0.0

# ... 修复 Bug ...
git add .
git commit -m "Fix critical-bug in production"
git push -u origin hotfix/critical-bug

# 创建PR,审查,合并 hotfix/critical-bug 到 main
git checkout main
git merge --no-ff hotfix/critical-bug
git tag v1.0.1 # 新的生产版本标签
git push origin main
git push origin v1.0.1

# 同时,将修复合并到 develop
git checkout develop
git pull origin develop
git merge --no-ff hotfix/critical-bug # 或者 cherry-pick 修复提交
git push origin develop

# 删除 hotfix 分支
git branch -d hotfix/critical-bug
git push origin --delete hotfix/critical-bug

关键 Git 命令汇总

查看分支:

git branch              # 列出本地分支
git branch -r           # 列出远程分支
git branch -a           # 列出所有分支
git branch --merged     # 列出已合并到当前分支的分支
git branch --no-merged  # 列出未合并到当前分支的分支

创建分支:

git branch <branch-name>                                # 创建分支
git checkout -b <branch-name> [start-point]             # 创建并切换到新分支,可选基于某个起点 (如另一分支或标签)

切换分支:

git checkout <branch-name>

合并分支:

git merge <branch-to-merge-into-current>          # 将指定分支合并到当前分支
git merge --no-ff <branch-to-merge>               # 创建一个合并提交,即使可以快进合并
git merge --squash <branch-to-merge>               # 将指定分支的多次提交合并为一个提交,然后需要手动 git commit

删除分支:

git branch -d <branch-name>                               # 删除已合并的本地分支 (安全)
git branch -D <branch-name>                               # 强制删除本地分支 (即使未合并)
git push origin --delete <remote-branch-name>              # 删除远程分支

同步与远程仓库:

git fetch origin                                          # 从远程仓库下载所有分支和提交,但不自动合并
git pull origin <branch-name>                               # 等同于 git fetch origin 后跟 git merge origin/<branch-name>
git push origin <branch-name>                               # 推送本地分支到远程
git push -u origin <branch-name>                              # 推送并设置上游跟踪分支

重命名分支:

git branch -m <old-name> <new-name>                      # 重命名本地分支
# (重命名远程分支较复杂:先重命名本地,推送新名称,删除旧远程名称)

总结与最佳实践

  • 始终为独立任务创建分支: 这是最核心的原则。
  • 保持分支短生命周期: 特性分支和 Bugfix 分支在合并后应立即删除。
  • 使用清晰的命名规范: 方便识别分支用途 (feature/, bugfix/, hotfix/, release/)。
  • 定期清理陈旧分支: git fetch --prune 清理本地不存在的远程跟踪分支,定期审查并删除远程不再需要的旧分支。
  • 善用 Pull/Merge Requests: 这是代码审查和讨论的绝佳工具。
  • 理解 --no-ff 合并: 它能保留分支的开发历史,使主干历史更易读。
  • 沟通: 团队应就分支策略达成一致并严格遵守。

选择合适的分支策略并坚持执行,将极大地提升开发效率、代码质量和团队协作的顺畅度。根据项目和团队的实际情况,可以对上述模型进行调整和简化。

Leave a Reply

Your email address will not be published. Required fields are marked *