跳到主要内容

Git 工作流与分支策略

本指南涵盖了 Git 工作流、分支策略、Conventional Commits 规范以及日常开发中的常用命令。

基础工作流

标准的 Git 工作流涉及将更改在三个主要区域之间移动:工作目录 (Working Directory)、暂存区 (Staging Area/Index) 和 仓库 (Repository/HEAD)。

理解 Git 的三个区域

Git 在三个不同的区域管理文件,每个区域都有特定的用途:

区域用途你看到的内容
工作目录您在磁盘上实际操作文件的地方,进行编辑最新状态的文件(编辑后的内容)
暂存区 (索引)准备区域,您在此选择要包含在下一次提交中的更改将包含在下一次提交中的文件快照
仓库 (HEAD)已提交更改的永久历史记录包含元数据(作者、日期、消息)的完整提交历史

关键区别:

  • 工作目录 vs 暂存区:工作目录包含您的最新编辑,而暂存区仅包含您使用 git add 明确标记的更改。您可以编辑文件十次,但只暂存最终版本。

  • 暂存区 vs 仓库:暂存区保存下一次提交的更改(临时),而仓库存储整个提交历史(永久)。只有 git commit 才能将更改从暂存区移动到仓库。

  • HEAD:指向当前检出的提交的指针,通常是当前分支上的最新提交。

各区域的操作命令

工作目录

命令用途
git status查看哪些文件已被修改
git diff查看尚未暂存的更改
git checkout -- <file>丢弃工作目录中的更改(恢复到最后提交的版本)
git restore <file>git checkout -- <file> 的现代替代命令

暂存区

命令用途
git add <file>暂存特定文件
git add .暂存所有已修改文件
git add -p交互式暂存(逐块选择)
git restore --staged <file>取消暂存文件(保留更改)
git diff --staged查看准备提交的更改
git reset取消暂存所有文件

仓库

命令用途
git commit -m "message"提交暂存的更改
git commit -am "message"提交所有已跟踪文件(跳过暂存)
git log --oneline查看提交历史
git show <hash>查看特定提交的详细信息
git reset --soft HEAD~1撤销最后一次提交,保留更改在暂存区
git reset --hard HEAD~1撤销最后一次提交,丢弃所有更改

常见陷阱与安全规则

了解这些风险有助于防止数据丢失和仓库损坏。

关键规则
  1. 尽量不要强制推送到共享分支maindevelop)- 如必须强制推送,使用 --force-with-lease 并提前沟通/确认
  2. 避免改写共享分支上已发布的历史 - 在常规工作流中,已推送的提交应视为不可变
  3. 执行破坏性操作前先检查 - 运行 git statusgit diff
  4. 使用 git reflog 恢复 - 可恢复丢失的提交
区域风险预防措施
工作目录使用 git checkout -- <file> 丢弃未提交的工作丢弃前检查 git diff
暂存区使用 git add . 意外暂存过多内容使用 git add -p 交互式暂存
仓库git reset --hard 永久丢弃提交创建备份分支:git branch backup
安全工作流
  • 对共享历史使用 git revert 而非 git reset
  • 使用 git reset --soft 撤销提交而不丢失更改
  • 切换分支前先提交或 stash

分支策略

选择合适的分支策略取决于团队规模和发布频率。

Git Flow

最适用于: 定期发布和版本化产品。

  • main: 仅限生产就绪代码。
  • develop: 功能集成分支。
  • feature/: 新功能临时分支。
  • release/: 新生产版本准备分支。
  • hotfix/: 生产环境 Bug 紧急修复。

GitHub Flow

最适用于: 持续部署 (CD) 和 Web 应用程序。

  • main 分支始终保持可部署状态。
  • main 创建短周期的功能分支。
  • CI/CD 通过后,通过 Pull Request 合并回 main

约定式提交 (Conventional Commits)

标准化提交信息使历史记录清晰可读,并能实现自动生成变更日志 (Changelog)。

格式: <type>(<scope>): <subject>

类型用途示例
feat新功能feat(auth): add JWT support
fixBug 修复fix(api): handle null response
docs仅文档更新docs: update readme
refactor代码重构(不修复 Bug 也不增加功能)refactor: simplify loop
chore维护(构建、依赖、工具)chore: update docusaurus
原子性

保持提交的原子性。一个提交应代表一个逻辑变更。这使 git revertgit cherry-pick 更加安全。


常用命令

历史与检查

命令用途
git status -s简短状态摘要
git diff --staged查看已加入暂存区的更改
git log --oneline --graph --all所有分支的可视化展示
git blame <file>识别每一行的修改者

撤销与恢复

命令效果场景
git commit --amend修改最后一个提交遗漏文件或提交信息拼写错误
git reset --soft HEAD~1撤销提交,保留更改在暂存区重新正确提交
git reset --hard HEAD~1破坏性:回退到上一状态丢弃不需要的工作
git revert <hash>创建一个撤销之前提交的新提交安全地撤销已推送的提交
强制推送

切勿在 maindevelop 等共享分支上使用 git push --force。如果必须在变基后更新远程分支,请使用 git push --force-with-lease


高级工具

Git Stash

临时保存未提交的更改以切换分支。

  • git stash: 保存工作
  • git stash pop: 恢复工作

Git Worktree

管理多个工作目录,它们都指向同一个仓库,让你可以同时检出不同分支而无需 stash 或切换。

为什么使用 Worktree?

没有 Worktree 的痛点使用 Worktree 的解决方案
切换分支前需要 git stash每个分支一个目录,无需 stash
长时间构建阻塞分支切换在一个工作树中构建,在另一个中编辑代码
对比分支需要 git diff在两个目录中打开编辑器直接对比

核心命令

命令用途
git worktree add <路径> <分支><路径> 创建新的工作树并检出 <分支>
git worktree add -b <新分支> <路径> <起点>同时创建新分支和工作树
git worktree list列出所有关联的工作树
git worktree remove <路径>移除工作树(不会删除分支)
git worktree prune清理过期的工作树条目(如手动删除目录后)

示例工作流

# 你正在 main 上开发新功能
# 突然需要对生产分支 v2.0 做 hotfix

# 1. 为 hotfix 创建工作树(无需 stash 任何东西)
git worktree add ../hotfix-dir v2.0

# 2. 在独立目录中修复 Bug
cd ../hotfix-dir
# ... 编辑、提交、推送 ...
git push origin v2.0

# 3. 回到原来的工作
cd ../project
# 功能分支仍在原来的位置,一切未变

# 4. 清理 hotfix 工作树
git worktree remove ../hotfix-dir
命名规范

为工作目录使用统一的前缀,如 ../project-hotfix../project-review../project-release,保持工作区整洁。

警告

同一分支同时只能在一个工作树中检出。尝试在两个工作树中检出相同分支会失败。

Git Bisect

通过二分查找确定引入 Bug 的提交。

  • git bisect start
  • git bisect bad
  • git bisect good <stable-hash>

相关指南