← 中文资源

简体中文版本

Git 合并冲突 — 正确解决标记且不丢失改动

列出未合并路径,读取双方 diff 并理解意图,解决 Git 冲突标记后运行测试与 diff 检查再提交,必要时安全中止合并。

阅读英文原文

现象

Git 提示 Automatic merge failed; fix conflicts and then commit the result.;git status 显示 both modified: src/app.ts;文件中出现 <<<<<<< HEAD、=======、>>>>>>> feature/login 标记;rebase 或 cherry-pick 停在 CONFLICT。

诊断

先拿到完整的未合并清单:

git status --short
git diff --name-only --diff-filter=U
git diff -- src/app.ts

UU 表示双方都修改,DU/UD 是删除与修改冲突,AA 是双方都新增,重命名冲突不会出现文本标记,必须单独处理。查看 diff 时结合上下文理解两边意图,而不是按行号挑一边。也可分别导出两个阶段对比:

git show :2:src/app.ts > /tmp/ours.ts
git show :3:src/app.ts > /tmp/theirs.ts
diff -u /tmp/ours.ts /tmp/theirs.ts | head -80

阶段 2 是 ours,阶段 3 是 theirs;rebase 时二者相对分支名的含义会反转,操作前先确认当前是 merge 还是 rebase。若差异覆盖每一行,多半是换行符或格式化问题,应统一 .gitattributes 而不是手工合并。

修复

按业务意图合并两边逻辑,删除全部冲突标记后 git add 再提交。只有确认某一侧完全错误时才使用 git checkout --ours 或 --theirs,且合并后必须重跑测试。若暂时不值得完成合并,git merge --abort 或 git rebase --abort 可恢复操作前状态。

验证

执行 git diff --check 与 grep -rn '^<<<<<<<\|^>>>>>>>' src/ 确认没有残留标记,git status 不再有未合并路径,受影响测试全部通过,并在提交前审查最终 diff。不要提交仍含冲突标记的文件,那会直接破坏构建。