Git合并冲突需先区分语义冲突与字节冲突;用git diff --no-index等命令验证真假冲突,再针对性解决,避免误删标记或逻辑错误。

Git 合并冲突不是“必须手动删标记”,而是要先判断冲突类型:是语义冲突(真改了同一行),还是字节冲突(编码、换行符、BOM 导致的假冲突)。绝大多数人卡在第一步——没区分清楚就硬解,结果下次合并还爆。
用 git diff --no-index 快速验证是不是编码/换行符问题
别急着打开文件删 <<<<<< HEAD。先确认冲突是否“真实”:
- 运行
git diff --no-index --ignore-space-at-eol --ignore-cr-at-eol path/to/file1 path/to/file2,把两个冲突版本导出为临时文件再比对 - 如果输出只有
^M(CRLF)、EF BB BF(UTF-8-BOM)或空格增减,基本就是编码/换行惹的祸 - 用
file -i 文件名(Linux/macOS)或 Windows 记事本「另存为」看编码,确认两边一个是 UTF-8-BOM、另一个是 UTF-8 或 GBK -
git status显示both modified,但git diff全红全绿、无实际逻辑变更 → 90% 是字节冲突
手动解决语义冲突时,别直接编辑冲突标记
Git 插入的 <<<<<< HEAD / ======= / >>>>>> branch-name 只是提示位置,不是必须保留的格式:
适用于以下场景:(1)用户提供 GitHub 仓库 URL 或本地仓库路径,并请求将其转换为其他格式;(2)用户请求导出 GitHub 仓库……
- 真正要保留的是逻辑:你想要
HEAD版本的代码?还是branch-name的?还是两者融合?标记本身不参与编译/运行,删干净再写更安全 - IDEA 或 VS Code 的「Accept Current Change」「Accept Incoming Change」按钮会自动清理标记,但注意:它不会帮你做逻辑判断,选错就丢代码
- 如果冲突块里有函数签名变更、参数顺序调整、条件分支嵌套变化,建议把两边完整代码块复制到临时文本对比,再手写终版,别靠肉眼扫标记行
- 改完后必须
git add 冲突文件,否则git commit会报错:「You have not concluded your merge (MERGING)」
用 git mergetool 配 Beyond Compare 或 VS Code 跳过手动拼接
当冲突文件多、结构复杂(比如 JSON、XML、YAML 或大段 JSX/TSX),命令行看标记容易漏行:
- 先配好工具:
git config --global merge.tool bc3(Beyond Compare)或git config --global merge.tool vscode - 运行
git mergetool,它会自动唤起图形界面,左侧是本地(CURRENT),右侧是传入分支(INCOMING),中间是工作区(RESULT) - VS Code 的 Merge Editor 支持点击区块「Accept Current」或「Accept Incoming」,也支持拖拽合并;Beyond Compare 可逐行高亮差异并一键同步
- 保存退出后,工具会自动执行
git add,不用再手动暂存 —— 但记得检查中间面板是否真符合预期,别点太快
最常被忽略的一点:冲突解决完 git commit 生成的是一次「merge commit」,它的父提交有两个(HEAD 和被合并分支 tip)。如果你之后想回退,不能只 git reset --hard HEAD~1,得用 git reset --hard HEAD^2(取第二个父提交)或 git revert -m 1 <merge-commit>。编码统一和语义合并,是两件事,混着做只会让下一次合并更难。

















