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 | 撤销最后一次提交,丢弃所有更改 |
常见陷阱与安全规则
了解这些风险有助于防止数据丢失和仓库损坏。
- 尽量不要强制推送到共享分支(
main、develop)- 如必须强制推送,使用--force-with-lease并提前沟通/确认 - 避免改写共享分支上已发布的历史 - 在常规工作流中,已推送的提交应视为不可变
- 执行破坏性操作前先检查 - 运行
git status和git diff - 使用
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 |
fix | Bug 修复 | fix(api): handle null response |
docs | 仅文档更新 | docs: update readme |
refactor | 代码重构(不修复 Bug 也不增加功能) | refactor: simplify loop |
chore | 维护(构建、依赖、工具) | chore: update docusaurus |
保持提交的原子性。一个提交应代表一个逻辑变更。这使 git revert 和 git 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> | 创建一个撤销之前提交的新提交 | 安全地撤销已推送的提交 |
切勿在 main 或 develop 等共享分支上使用 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 startgit bisect badgit bisect good <stable-hash>
相关指南
- 📄 Merge、Rebase 与 Cherry-Pick — 分支集成与历史改写。
- 📄 Git Hooks 指南 — 自动化代码检查和测试。
- 📄 子模块 (Submodules) 指南 — 管理外部依赖。
- 📄 SSH 设置 — 安全远程访问。