在路由器固件二次开发、OpenWrt 编译或内网路由脚本协同维护时,经常要拉取上游代码更新。一不小心 git merge 或 git pull 就报错:CONFLICT (content): Merge conflict in xxx,接着 git status 里一堆红色文件,还卡着 merging 状态——这时候想退回重来,却发现 git reset --hard 不顶用,git checkout . 也提示“无法在合并中丢弃更改”。别急,这不是 Git 坏了,是它还在等你拍板。
先看清楚当前到底卡在哪
执行下面这句,一眼看清状态:
git status
如果输出里有 you have unmerged paths,或者文件名旁边标着 both modified,说明确实卡在合并中。此时不能直接 commit,也不能随便删 .git/MERGE_HEAD ——那是 Git 的“记事本”,删了反而更乱。
想彻底放弃合并,回到合并前的样子
最干脆的办法:取消整个合并动作,退回到 merge 前的 HEAD。命令只有一行:
git merge --abort
这个命令专为这种情况设计,会自动清理 MERGE_HEAD、MERGE_MSG、.git/index 中的冲突标记,并恢复工作区和暂存区到合并开始前的状态。比手动 git reset --hard + git clean -fd 更安全,也不用担心误删自己改过的配置文件。
如果已经手抖删了 MERGE_HEAD,或者 --abort 报错
偶尔遇到 fatal: There is no merge to abort,可能是 .git/MERGE_HEAD 被误删,但 index 还残留冲突标记。这时可以补一刀:
git reset --merge
--merge 比 --hard 温和,它只重置暂存区和工作区中与合并相关的部分,不会动你还没 add 的本地修改(比如你刚改完的 /etc/config/network)。
顺手清理“假冲突”残留
有时候冲突解决了、也 commit 了,但 git status 还显示 merging ——大概率是上次 merge 没彻底收尾。检查下有没有残留文件:
ls -a .git | grep -E "MERGE|CHERRY"
看到 MERGE_HEAD、MERGE_MODE、MERGE_MSG 就直接删:
rm -f .git/MERGE_*
然后再跑一遍 git status,应该就清爽了。
小提醒:路由项目里特别注意的点
在 OpenWrt 或 Padavan 这类嵌入式路由项目中,常有人把 .config 或 files/ 目录一起提交。这类文件一旦起冲突,别光靠 git checkout --ours 硬选——先确认你本地的配置是不是真能用,否则刷机后 WAN 口没 IP 就得蹲后台重刷了。稳妥做法:先 git merge --abort,再用 make menuconfig 重新生成 .config,最后干净地 rebase 或 cherry-pick 补丁。