Git 分支太乱?你需要一把「梳子」——5 个命令救活你的 Git 历史
Git 分支太乱?你需要一把「梳子」——5 个命令救活你的 Git 历史
你打开 git log --oneline,满屏都是 fix、hotfix、wip、asdf、临时提交……
你试过 git rebase -i,结果冲突解了半小时,最后 git rebase --abort 回到原点。
你不是一个人。我见过一个团队的 Git 历史,120 个分支,其中 87 个已经合并不了了。master 上的 commit message 写着"最终版2"、"最终版2.1"、"真的最终版"。
今天这把「梳子」,就是 5 个 Git 命令,专门治分支混乱。不是理论,是我从三个烂摊子项目里救回来的实战经验。
---
第一把梳子:`git log --graph` — 先看清楚到底多乱
在动手之前,你得先看清现状。
# 看最近 20 个 commit 的分支图
git log --oneline --graph --all -20
输出类似这样:
- a3f2d1c (HEAD -> feature/login) fix: 登录接口超时
- 8b1e4a2 feat: 添加登录页面
| * c9d3f5a (feature/payment) wip: 支付功能半成品
| * 1a2b3c4 feat: 支付接口初始化
|/ - f7e6d5b (main) release: v2.1.0
5c4b3a2 fix: 修复首页白屏
这一步的目标不是改什么,就是看。看看有多少分支、哪些分叉了、哪些已经落后 main 很多了。
一句话总结:动手之前先看图,别盲目操作。
第二把梳子:`git branch --merged` — 找出已经合了但没删的分支
# 查看已经合并到 main 的分支(可以安全删除) git branch --merged main输出:
feature/login
fix/header-bug
hotfix-0520
* main
一行命令全删(main 和当前分支除外)
git branch --merged main | grep -v "^*|main|master" | xargs git branch -d
我上次在一个项目跑这个命令,一次性删了 34 个已经合并但没人清理的分支。Git 分支列表瞬间清爽。
一句话总结:合并了的分支不删,就像用完的文件不收,迟早堆成山。
第三把梳子:`git rebase -i` — 把"临时提交"压缩成一个
这是最强大也最危险的命令。先看场景:
# 你的 feature 分支上有 7 个 commit: # a3f2d1c fix: typo # 8b1e4a2 fix: 又一个 typo # c9d3f5a wip: 临时保存 # 1a2b3c4 feat: 核心功能 # f7e6d5b feat: 初始化模块 # 5c4b3a2 docs: 写了个注释 # 4b3a2c1 wip: 下班前提交你想把这 7 个压成 1 个干净的 commit
git rebase -i HEAD~7
编辑器会打开,内容类似:
pick f7e6d5b feat: 初始化模块
pick 1a2b3c4 feat: 核心功能
pick c9d3f5a wip: 临时保存
pick 8b1e4a2 fix: 又一个 typo
pick a3f2d1c fix: typo
pick 5c4b3a2 docs: 写了个注释
pick 4b3a2c1 wip: 下班前提交
改成这样:
pick f7e6d5b feat: 初始化模块
squash 1a2b3c4 feat: 核心功能
squash c9d3f5a wip: 临时保存
squash 8b1e4a2 fix: 又一个 typo
squash a3f2d1c fix: typo
squash 5c4b3a2 docs: 写了个注释
squash 4b3a2c1 wip: 下班前提交
保存退出,Git 会让你写一个新的 commit message:
feat: 用户登录模块
- 实现登录/注册接口
- 添加 JWT 认证
补充单元测试
7 个乱七八糟的 commit 变成 1 个清清楚楚的。
坑在这里:如果这个分支已经 push 到远程了,rebase 后需要 git push --force-with-lease。千万别在 main/master 上做 rebase,只在自己的 feature 分支上操作。
# 安全的强制推送(会检查远程是否有新 commit)
git push --force-with-lease origin feature/login
一句话总结:rebase 是把散装 commit 打包成礼盒,但别在公共分支上用。
第四把梳子:`git stash` — 暂存半成品,切换分支不慌
你正在 feature/payment 上写代码,写到一半,线上出 bug 了要切到 main 修。怎么办?
# 当前修改暂存起来 git stash push -m "支付功能写了一半"切到 main 修 bug
git checkout main
git checkout -b hotfix/login-crash... 修完 ...
git checkout main
git merge hotfix/login-crash回到支付分支,恢复之前的进度
git checkout feature/payment
git stash pop如果 stash 了多个,查看列表
git stash list
stash@{0}: On feature/payment: 支付功能写了一半
stash@{1}: On feature/login: 接口调了一半
一个真实案例:我有一次 stash 了 5 个东西没清理,过了两周完全忘了 stash@{2} 和 stash@{3} 是什么。后来发现是两个已经不需要的实验代码。
建议:stash 超过 3 天还没 pop 的,大概率不需要了。git stash drop 清理掉。
一句话总结:stash 是临时停车场,不是长期仓库。
第五把梳子:`git cherry-pick` — 精确搬运 commit
有时候你需要把某个 commit 从一个分支"搬"到另一个分支,但不想 merge 整个分支。
# 场景:feature/payment 上有个紧急修复 commit # 但 payment 分支还没做完,不能整体合并到 main先找到那个 commit 的 hash
git log feature/payment --oneline
a3f2d1c fix: 支付金额计算溢出 <- 就是这个
c9d3f5a wip: 支付功能半成品
1a2b3c4 feat: 支付接口初始化
切到 main,精确搬运这一个 commit
git checkout main
git cherry-pick a3f2d1c如果有冲突,解决后继续
git add .
git cherry-pick --continue
使用场景:
一句话总结:cherry-pick 是精确手术刀,一次只搬一个 commit。
附:分支命名规范(救不了历史,但能防未来)
feat/user-login # 新功能
fix/login-crash # Bug 修复
hotfix/payment-overflow # 线上紧急修复
refactor/auth-module # 重构
docs/api-readme # 文档
chore/deps-update # 杂务(依赖升级等)
别再用 wip、test、临时、最终版2.1 了。每一个含糊的分支名,都是给未来的自己挖坑。
---
一句话总结
Git 乱不可怕,可怕的是乱了还不梳理。这 5 个命令——log --graph 看清现状、branch --merged 清理已合并、rebase -i 压缩提交、stash 暂存半成品、cherry-pick 精确搬运——够你把 90% 的烂摊子救回来了。
别把它想复杂了。
关注「安全值班室」公众号
每天AI安全早报 + 实战攻防案例 + 网安学习路线连载
浙公网安备 33010602011771号