为什么依次git pull两个分支会删除首个分支的修改且无冲突?
问题产生原因
- 这是Git文本合并逻辑的固有特性,不是bug:Git的merge和rebase操作都是基于文本行块的差异做判断,完全不理解代码语义。你的场景里branchA和branchB都是从旧版本master切出的平行分支:如果branchA只改了1.txt的某几行,而branchB的提交刚好删除、重写、整块替换了包含这几行的连续文本段,Git会判定branchA修改的行已经在branchB中被移除,属于不需要保留的无效修改,会直接采用branchB的整块内容,全程不会报冲突。
- 不规范的操作流程直接触发了这个问题:你在master分支先后pull两个完全没做过代码同步的平行功能分支,相当于把两次跨分支合并的判断权完全交给Git的自动逻辑。Git只保证合并结果符合文本差异规则,不保证结果符合你的业务预期,只要文本判断不触发冲突阈值就会自动生成合并提交。
- 如果你本地配置了特殊合并策略,比如给pull默认加了
-X theirs/-X ours参数,Git遇到本该提示冲突的场景也会自动选边覆盖,不会弹出任何提示。 - 别误解
git pull的作用:它本质是git fetch + 合并(merge或rebase,取决于你的本地配置)的组合命令,不是“把另一个分支的修改增量叠加到当前分支”,只要两个分支存在提交分叉,自动合并就可能出现符合Git规则但不符合你预期的结果。
预防方案
- 先规范分支合入流程:不要直接在master这类主干分支上pull未合入的功能分支。正确流程是功能分支开发完后,先把最新的master代码合入/变基到功能分支,在功能分支上解决完冲突、验证功能正常后,再把功能分支合入master。
- 合并完必须做校验,别盲信Git的自动合并结果:不管是手动merge还是pull触发的自动合并,push之前一定要做两步检查:
- 执行
git log --oneline -n 5确认提交线符合预期 - 针对merge提交执行
git diff HEAD^1 HEAD,遍历本次合并的所有变更,重点核对两个分支都改过的文件,确认两边的有效修改都被保留,没有异常丢内容
- 执行
- 合并高重叠分支时关闭自动提交:如果两个分支修改的文件重合度很高,合并时加
--no-commit参数,比如git merge --no-commit branchB,合并完成后不会自动提交,你可以逐个检查修改过的文件,确认内容无误后再手动commit。 - 避免使用隐式自动选边的合并参数:不要随便给pull/merge加
-X theirs/-X ours,这类参数会跳过冲突提示直接选用其中一边的内容,非常容易造成无感知的代码丢失。 - 可以开启冲突展示优化配置:全局执行
git config --global merge.conflictstyle diff3,后续遇到显式冲突时会同时显示共同祖先版本、当前分支版本、目标分支版本,降低冲突解决时的误判概率。注意这个配置只对显式冲突生效,解决不了无冲突丢代码的问题,核心校验还是要靠人工完成。
内容的提问来源于stack exchange,提问作者Ben.S
相关产品推荐
相关产品推荐

