前言

Git 是现代软件开发的必备技能,而分支管理是 Git 的灵魂。无论是个人项目还是团队协作,合理的分支策略能让开发流程井井有条。本文聚焦于 Git 分支的实战操作与团队协作工作流。

为什么需要分支?

分支让你可以在不影响主线代码的情况下进行功能开发、Bug 修复或实验。每个人在自己的分支上工作,完成后合并回主线。


一、分支基础操作

1.1 查看分支

1
2
3
4
5
git branch                 # 查看本地分支
git branch -a # 查看所有分支(含远程)
git branch -v # 查看分支最后一次提交
git branch --merged # 查看已合并到当前分支的分支
git branch --no-merged # 查看未合并的分支

1.2 创建与切换分支

1
2
3
4
5
6
7
8
git branch feature-login   # 创建分支
git checkout feature-login # 切换分支

# 创建并切换(一步到位)
git checkout -b feature-payment

# 新版 Git 推荐使用 switch
git switch -c feature-payment

1.3 删除分支

1
2
3
4
5
git branch -d feature-login       # 安全删除(已合并的)
git branch -D feature-login # 强制删除(未合并也删除)

# 删除远程分支
git push origin --delete feature-login

1.4 重命名分支

1
2
git branch -m old-name new-name          # 重命名当前分支
git branch -m old-name new-name # 重命名其他分支

二、合并策略:Merge vs Rebase

这是 Git 中最需要理解的概念之一。

2.1 git merge — 合并分支

1
2
3
# 在 main 分支上执行,将 feature 分支合并进来
git checkout main
git merge feature-login

效果:生成一个新的”合并提交”(merge commit),保留完整历史。

1
2
3
main:     A---B---C---M (merge commit)
/
feature: D---E---

适用场景:合并功能分支到公共分支,保留完整上下文。

2.2 git rebase — 变基

1
2
3
# 在 feature 分支上执行,将当前分支的提交接到 main 最新提交之后
git checkout feature-login
git rebase main

效果:重写历史,让提交历史变成一条直线。

1
2
3
4
5
6
7
# rebase 前
main: A---B---C
feature: D---E

# rebase 后
main: A---B---C
feature: D'---E'

⚠️ 黄金法则:永远不要 rebase 已经推送到远程的公共分支!

2.3 什么时候用哪个?

场景 推荐 原因
合并 feature → main merge 保留历史,明确追溯
同步 main 最新代码到 feature rebase 保持 feature 历史整洁
整理本地提交记录 rebase -i 压缩、重排提交
Pull 远程代码 pull --rebase 避免无意义的 merge commit

2.4 交互式 rebase — 清理提交历史

1
2
# 整理最近 3 次提交
git rebase -i HEAD~3

进入编辑界面后:

1
2
3
4
5
6
7
8
9
pick a1b2c3d 添加登录功能
pick e4f5g6h 修复登录页样式
pick i7j8k9l 修复登录逻辑 bug

# 可以改为:
pick a1b2c3d 添加登录功能
squash e4f5g6h 修复登录页样式 # 合并到上一个提交
squash i7j8k9l 修复登录逻辑 bug # 合并到上一个提交
# 最终只保留一个干净的提交

常用命令

命令 含义
pick 保留该提交
squash 合并到上一个提交,保留 commit message
fixup 合并到上一个提交,丢弃 commit message
drop 删除该提交
reword 修改 commit message

三、解决冲突

当两个分支修改了同一文件的同一行时,合并会产生冲突。

3.1 冲突示例

1
2
3
4
git checkout main
git merge feature-login
# CONFLICT (content): Merge conflict in src/app.js
# Automatic merge failed; fix conflicts and then commit the result.

3.2 手动解决冲突

Git 会在冲突文件中标记:

1
2
3
4
5
<<<<<<< HEAD
console.log("main 分支的代码");
=======
console.log("feature 分支的代码");
>>>>>>> feature-login

手动编辑文件,保留需要的内容,删除标记:

1
console.log("合并后的最终代码");
1
2
git add src/app.js           # 标记为已解决
git commit # 完成合并(Git 会自动生成 merge message)

3.3 使用工具

1
2
3
4
5
# 使用可视化工具
git mergetool

# VS Code 内置的三路合并编辑器非常好用
# 绿色背景 = 当前分支 | 蓝色背景 = 传入分支

3.4 中止合并/变基

1
2
git merge --abort            # 取消合并,回到合并前状态
git rebase --abort # 取消变基

四、实用分支操作

4.1 cherry-pick — 挑选提交

将某个提交”摘”到当前分支:

1
2
3
# 在 main 分支,想把 feature 分支的某个提交应用到 main
git checkout main
git cherry-pick a1b2c3d

场景:紧急修复了一个 bug,需要同时应用到多个版本分支。

4.2 stash — 暂存修改

切换分支时如果当前有未提交的修改:

1
2
3
4
5
6
7
8
9
10
git stash                    # 暂存当前修改
git checkout other-branch # 切换分支做事
git checkout original-branch # 切回来
git stash pop # 恢复之前的修改

# 常用 stash 命令
git stash list # 查看暂存列表
git stash apply stash@{1} # 恢复指定暂存(不删除)
git stash drop stash@{1} # 删除指定暂存
git stash save "描述信息" # 带描述的暂存

4.3 reflog — 救命稻草

即使误删了分支或提交,reflog 也能找回来:

1
2
3
4
5
6
git reflog
# a1b2c3d HEAD@{0}: commit: 添加新功能
# e4f5g6h HEAD@{1}: merge feature: Merge made by 'ort'

# 恢复到之前的状态
git reset --hard HEAD@{1}

4.4 reset vs revert

1
2
3
4
5
6
7
# reset:回到指定提交,之后的提交"消失"(修改历史)
git reset --soft HEAD~1 # 撤销提交但保留修改在暂存区
git reset --mixed HEAD~1 # 撤销提交和暂存,保留修改在工作区(默认)
git reset --hard HEAD~1 # 彻底删除提交和修改(危险!)

# revert:创建一个新提交来"撤销"之前的提交(不改历史,推荐用于公共分支)
git revert a1b2c3d

五、团队协作工作流

5.1 GitHub Flow(最流行)

1
2
3
4
main ─────────────────────────●──●── (随时可部署)
\ /
feature ●──●──●──●──●──●──
↖ PR Review → Merge

规则

  • main 分支始终可部署
  • 任何新工作从 main 创建 feature 分支
  • 完成后发起 Pull Request
  • Code Review 通过后合并到 main
  • 合并后立即部署
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 从 main 创建功能分支
git checkout main
git pull origin main
git checkout -b feature/user-profile

# 2. 开发,频繁提交
git add .
git commit -m "添加用户个人资料页"

# 3. 推送到远程
git push origin feature/user-profile

# 4. 在 Gitee/GitHub 上创建 Pull Request
# 5. 团队成员 Review 代码
# 6. 合并到 main

5.2 Git Flow(适合有版本发布的项目)

1
2
3
4
5
6
7
8
9
main     ●──────●────────────────●──── (生产版本)
\ / /
release ●──● (发布分支)
\ \ /
develop ●──●──●──●──●──● (开发主线)
\
feature ●──●──● (功能分支)
\
hotfix ●──● (紧急修复)

分支类型

分支 用途 从哪创建 合并到哪
main 生产环境代码
develop 开发主线 main
feature/* 新功能开发 develop develop
release/* 发布准备 develop main + develop
hotfix/* 紧急修复 main main + develop

5.3 Trunk-Based Development(主干开发)

适合持续集成成熟的团队:

1
2
3
main ●──●──●──●──●──●──●── (所有开发直接在 main 上)
\ \ \ \
● ● ● ● (极短生命周期的分支)

特点:分支存活不超过 1-2 天,通过 Feature Flag 控制新功能上线。


六、Pull Request 最佳实践

6.1 PR 标题规范

1
2
3
<类型>: <简短描述>

类型:feat / fix / docs / refactor / test / chore

6.2 PR 描述模板

1
2
3
4
5
6
7
8
9
10
11
12
13
## 变更说明
简要描述做了什么改动

## 变更类型
- [ ] 新功能 (feat)
- [ ] Bug 修复 (fix)
- [ ] 重构 (refactor)

## 测试
- [ ] 单元测试通过
- [ ] 手动测试通过

## 截图(如涉及 UI 变更)

6.3 Code Review 关注点

  • 逻辑是否正确
  • 是否有潜在的性能问题
  • 是否遵循项目编码规范
  • 是否有足够的测试覆盖
  • 是否有安全风险

七、常见场景速查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# === 场景1:撤销最后一次提交(保留修改)===
git reset --soft HEAD~1

# === 场景2:修改最后一次提交信息 ===
git commit --amend -m "新的提交信息"

# === 场景3:忘记创建分支就开始开发了 ===
git checkout -b feature-new
# 修改已经在工作区,直接在新分支上提交即可

# === 场景4:把当前分支的多个提交合并为一个 ===
git rebase -i HEAD~n

# === 场景5:从 main 同步最新代码到 feature ===
git checkout feature
git rebase main

# === 场景6:放弃本地所有修改 ===
git checkout . # 放弃工作区修改
git clean -fd # 删除未跟踪的文件

# === 场景7:查看某次提交的内容 ===
git show a1b2c3d
git show a1b2c3d --stat # 只看改了哪些文件

# === 场景8:查看是谁改了某一行 ===
git blame src/app.js -L 10,20

# === 场景9:比较两个分支的差异 ===
git diff main..feature

# === 场景10:临时切走,保存当前进度 ===
git stash
# ... 做别的事
git stash pop

八、Git 配置优化

1
2
3
4
5
6
7
8
9
10
11
12
13
# 设置别名,提高效率
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.lg "log --oneline --graph --all --decorate"
git config --global alias.undo "reset --soft HEAD~1"

# Pull 时默认使用 rebase
git config --global pull.rebase true

# 设置默认分支名
git config --global init.defaultBranch main

结语

Git 分支管理的关键不在于记住所有命令,而在于理解工作流团队规范。建议:

  • 个人项目用 GitHub Flow,简单高效
  • 有版本发布周期的项目用 Git Flow
  • 团队统一一种工作流,写入团队文档
  • 遇到问题先 git status 看看当前状态
  • 不确定的操作先 git branch 备份一下

掌握分支管理,你就掌握了 Git 的灵魂。🔀