git合并llvmorg-13.0.0时大量未修改文件报冲突如何解决?
我在执行git merge操作时遇到未修改文件报冲突的问题,具体情况如下:
我fork了llvm项目,本地main分支基于上游的llvmorg-12.0.0 tag构建,仅做了两处改动:新增2个文件、对2个上游现有文件做了小幅修改。
通过git diff --name-only llvmorg-12.0.0命令可以确认我仅改动了以下4个文件:
$ git diff --name-only llvmorg-12.0.0 .buildbot.sh # new file bors.toml # new file llvm/CMakeLists.txt # modified file llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp # modified file
我本地main分支在tig中的提交记录见附图:
现在我需要将分支同步到llvm最新版本llvmorg-13.0.0 tag,我已经执行了git fetch llvm拉取了上游所有提交和tag,之后我新建了合并分支:
$ git co -b sync-llvm13 Switched to a new branch 'sync-llvm13'
随后执行合并操作:
$ git merge llvmorg-13.0.0 Performing inexact rename detection: 100% (8537886/8537886), done. warning: Cannot merge binary files: llvm/test/tools/llvm-profgen/Inputs/recursion-compression-pseudoprobe.perfbin (HEAD vs. llvmorg-13.0.0) Removing polly/lib/External/isl/cpp/cpp.h.pre Removing polly/lib/External/isl/cpp/cpp-checked.h.pre CONFLICT (add/add): Merge conflict in openmp/runtime/test/tasking/hidden_helper_task/capacity_nthreads.cpp Auto-merging openmp/runtime/test/tasking/hidden_helper_task/capacity_nthreads.cpp Removing openmp/runtime/src/tsan_annotations.h Removing openmp/runtime/src/tsan_annotations.cpp Auto-merging openmp/runtime/src/kmp_tasking.cpp Auto-merging openmp/runtime/src/kmp_settings.cpp Auto-merging openmp/runtime/src/kmp_runtime.cpp Auto-merging openmp/runtime/src/kmp_config.h.cmake CONFLICT (content): Merge conflict in openmp/runtime/src/kmp_config.h.cmake Auto-merging openmp/runtime/src/CMakeLists.txt Auto-merging openmp/runtime/cmake/config-ix.cmake Auto-merging openmp/runtime/CMakeLists.txt CONFLICT (add/add): Merge conflict in openmp/libomptarget/test/offloading/bug49334.cpp Auto-merging openmp/libomptarget/test/offloading/bug49334.cpp CONFLICT (add/add): Merge conflict in openmp/libomptarget/test/offloading/bug49021.cpp Auto-merging openmp/libomptarget/test/offloading/bug49021.cpp CONFLICT (add/add): Merge conflict in openmp/libomptarget/test/offloading/assert.cpp ... Auto-merging clang/test/Preprocessor/riscv-target-features.c CONFLICT (content): Merge conflict in clang/test/Preprocessor/riscv-target-features.c Removing clang/test/Preprocessor/pragma_sysheader.h Auto-merging clang/test/Preprocessor/macro_vaopt_check.cpp CONFLICT (content): Merge conflict in clang/test/Preprocessor/macro_vaopt_check.cpp Auto-merging clang/test/OpenMP/teams_distribute_simd_codegen.cpp CONFLICT (content): Merge conflict in clang/test/OpenMP/teams_distribute_simd_codegen.cpp Auto-merging clang/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp CONFLICT (content): Merge conflict in clang/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp Auto-merging clang/test/OpenMP/teams_distribute_parallel_for_codegen.cpp ...loads more conflicts
合并时报出大量冲突,包含add/add、rename/delete、content三类冲突,且绝大多数冲突文件我从未修改过。查看其中一处content冲突的文件内容如下:
... <<<<<<< HEAD:libcxx/include/__support/openbsd/xlocale.h #include <__support/xlocale/__strtonum_fallback.h> ======= #include <cwctype> >>>>>>> llvmorg-13.0.0:libcxx/include/support/openbsd/xlocale.h ...
我已排除行尾符问题,确认自己从未编辑过这些冲突文件,使用的git版本为Debian 11系统下的2.33.0版本。请问是什么原因导致该问题?是否是我操作有误,需要用其他方式执行合并?
问题原因
这是跨大版本合并的正常现象,核心原因是两个合并分支的共同基础提交(合并基底)和目标版本之间存在海量上游改动。
你当前的分支基于llvmorg-12.0.0做了少量自定义修改,合并目标是llvmorg-13.0.0,两个大版本之间LLVM上游本身有上万次提交,包括文件增删、路径重命名(你贴出的冲突案例里,上游就把libcxx/include/support/路径改成了libcxx/include/__support/)、内容修改,这些上游改动和你当前分支的基底版本之间的差异,在合并时就会表现为冲突,和你有没有修改过这些文件没有关系。
更优同步方案
你本地只有4个文件的自定义改动,完全不需要走大版本合并的流程,用rebase操作更简单,冲突量极小:
- 先终止当前未完成的合并:
git merge --abort
- 基于上游
llvmorg-13.0.0新建空白同步分支:
git checkout -b sync-llvm13 llvmorg-13.0.0
- 把你本地main分支上的自定义提交rebase到新分支上:
git rebase main --onto sync-llvm13
- 此时只会在你修改过的4个文件上可能出现冲突,解决冲突后执行
git rebase --continue即可完成同步。
如果你的自定义改动只有1-2个提交,也可以直接用cherry-pick把对应提交拣到基于llvmorg-13.0.0的新分支上,操作更直观。
内容的提问来源于stack exchange,提问作者Edd Barrett

