git冲突本质是三方合并中head与theirs分支对同一代码行块(默认相邻3行)的互斥修改,需人工决策;非文件级而是逻辑区域级判定,fast-forward无冲突但协作中极少见。

冲突不是“改了同一个文件”,而是“改了同一块内容”
Git判断冲突的最小单位不是文件,而是代码行块。即使两个分支都修改了 config.yml,只要改的是第5行和第50行,Git会自动合并,不会报错。只有当改动落在「同一段逻辑区域」(默认是相邻3行内),且修改内容不一致时,才触发冲突。比如:A分支把 timeout: 30 改成 timeout: 60,B分支在同一位置改成 timeout: 45,Git无法推断哪个值更合理,只能停住让你选。
三方合并(three-way merge)才是冲突判定的真实依据
Git做 git merge 时,实际比对的是三个版本:common ancestor(两个分支最后一次共同提交)、HEAD(当前分支最新状态)、theirs(待合并分支最新状态)。只有当「HEAD 相对于祖先的改动」和「theirs 相对于祖先的改动」在相同位置产生互斥变更,才会标为冲突。这意味着:如果你本地没动过某行,哪怕远程改了,也不会冲突;但如果你本地删了某段函数,而别人在那行加了注释,就属于「删 vs 改」,直接冲突。
git pull 报冲突,本质是 fetch + merge 的副作用
git pull 不是独立操作,它等价于先 git fetch 拉取远程新 commit,再自动执行 git merge。所以你看到的冲突,其实是 merge 阶段抛出的。常见误操作包括:
使用约定式提交信息暂存、提交和推送git更改。当用户想要提交和推送更改、提到推送到远程、或要求保存并推送工作时触发。也适用于用户说“推送更改”、“提交并推送”、“推送这个”、“推送到github”或类似git工作流程请求时。
- 本地有未提交修改(
git status显示 modified),此时pull会尝试把远程改动和你的脏工作区合并——极大概率冲突 - 远程分支已由他人 push 过新提交,而你上次
pull是2小时前,中间积累的差异越大,冲突概率越高 - 用了
git stash但忘记git stash pop,导致你以为工作区干净,实际暂存区还压着旧修改
fast-forward 合并不会产生冲突,但现实里几乎遇不到
当目标分支(如 main)没有任何新提交,而你要合并的分支(如 feature)只是在它基础上多几个 commit,Git 就会用 fast-forward 方式移动指针,不生成新 commit,也不触发三路比对——自然无冲突。但团队协作中,main 几乎总在持续收其他人的 PR,所以你日常遇到的 99% 合并都是三方合并,冲突是常态,不是异常。
真正容易被忽略的点是:冲突标记( 等)只出现在具体文件里,但冲突根源永远在分支历史拓扑中。不看 <code>git log --oneline --graph,光盯着报错信息,很容易把问题归因到“谁改错了”,而不是“我们多久没同步主干了”。










