git branch --no-merged 是最直接的命令,用于列出尚未被当前 head 包含的本地分支,仅基于本地提交图谱判断,不涉及远程分支或 reflog,删除的分支不会出现在结果中。

git branch --no-merged 是最直接的命令
想立刻知道哪些分支还没合并进当前分支,git branch --no-merged 就是答案。它只列出那些**尚未被当前 HEAD 所包含**的分支——也就是还“悬着”的功能分支或实验分支。
这个命令不关心远程分支是否存在,也不检查是否推送到远端,只基于本地提交图谱做拓扑判断。所以只要本地有该分支的引用(哪怕只是曾经 checkout 过),它就可能出现在结果里。
- 运行前确保你在目标基线分支上(比如
git checkout main或git checkout master) - 如果当前在
dev分支,git branch --no-merged查的是“哪些分支没合并进dev” - 它不会显示已删除但 reflog 还残留的分支;那些得靠
git reflog挖
为什么有时候 --no-merged 不显示刚删掉的分支
刚用 git branch -d feature/login 删除的分支,大概率不会出现在 --no-merged 结果中——不是命令失效,而是它已经从分支引用列表里彻底移除了。
Git 的 --no-merged 只扫描现存的分支指针(refs/heads/*),不扫描 reflog 或 dangling commit。所以一旦分支被删,它就“不可见”了,哪怕那些提交根本没被任何其他分支指向。
- 想找回这类分支,必须立刻执行
git reflog,找类似feature/login@{0}: checkout: moving from main to feature/login的记录 - 然后用
git branch feature/login <code>HEAD@{n}重建(把n换成 reflog 中对应序号) - 如果已经执行过
git gc或隔了太久,reflog 条目可能被清理,恢复就不可逆
配合 git log 看未合并分支的活跃度
git branch --no-merged 只给名字,没法判断哪个该优先处理。这时候加一行 git log -1 --oneline <branch-name></branch-name> 就能快速看出最后提交时间与内容。
更省事的做法是批量查:用 shell 循环或 xargs 把所有未合并分支的最新提交摘要打出来:
git branch --no-merged | sed 's/^..//' | xargs -I {} sh -c 'echo "== {} =="; git log -1 --oneline {}'
注意 sed 's/^..//' 是为了去掉 git branch 默认输出前面的两个空格和可能的星号。
- 如果某分支最新提交是 3 个月前,且 message 是 “WIP” 或 “temp”,大概率可以安全丢弃
- 如果多个未合并分支都改了同一个文件,合并时冲突概率高,建议先 rebase 或协调顺序
-
git log --cherry-pick --oneline A...B可进一步比对两个未合并分支之间是否有重复提交
远程分支未合并?--no-merged 默认不查
git branch --no-merged 只查本地分支。如果你想知道哪些远程分支(如 origin/feat/api-v2)还没合并进本地 main,得先同步远程引用:git fetch --prune,再手动比对。
常用组合是:
git branch -r --format='%(refname:short)' | grep -v '\->' | while read r; do git merge-base --is-ancestor ${r#origin/} main || echo $r; done
这段脚本的意思是:列出所有远程分支名(去掉 origin/ 前缀),逐个检查它是否是 main 的祖先;如果不是,说明它没被合并。
- 别忘了
git fetch --prune必须先跑,否则远程分支列表可能过期 - 远程分支名带斜杠(如
origin/bugfix/123)会被git merge-base正确识别,但不能直接传给它带origin/前缀的完整 ref,得用${r#origin/}截掉 - 这种检查开销略大,不建议在 CI 脚本里高频调用











