`git merge` 报告我没有更改的文件的冲突
`git merge` reports conflicts for files that I have not changed
我想了解以下(已尝试)git 合并的情况。
我有一个 llvm 的分支,其中 main
分支是上游的 llvmorg-12.0.0
标记,加上:
- 两个新文件。
- 现有上游文件的两个小改动。
我们可以通过这样做看到我在我的分支中触及的文件:
$ 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
标签。我已经 git fetch llvm
获取了所有上游的提交和标签。
让我们先创建一个分支来进行合并:
$ 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
冲突之一,文件中确实存在冲突标记(例如 libcxx/include/__support/openbsd/xlocale.h
):
...
<<<<<<< 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 diff --only-name
命令,我从未编辑过这些文件。
有什么进展吗?
用户error/misconception?我应该以不同的方式合并吗?
这是在 Debian 11 上使用最新的 git (2.33.0)。
如果标签 llvmorg-12.0.0
无法通过标签 llvmorg-13.0.0
访问,这可以解释。
换句话说,checkout tag 12,尝试合并tag 13,可能会冲突。如果您这样做(显然)与您的代码无关,这仅意味着该回购协议的维护者使用的分支策略不一定包括将已发布的标签合并回 main
。或者即使他们最终这样做了,他们也没有在这两个版本之间这样做。
您还可以使用此命令测试标签 12 是否可以从标签 13 访问(在 Git Bash 或 *nix shell 中):
git rev-list llvmorg-13.0.0 | grep `git rev-parse llvmorg-12.0.0`
命令的“rev-list”部分列出了所有可从标签 13 访问的提交,然后它会查看标签 12 的提交 ID 是否是其中之一。
如果没有任何输出,那么这就是正在发生的事情。
从您的合并输出中,您看到的带有 CONFLICT (add/add)
的行表明回购维护者从 release-12 分支中挑选了一些提交回到 main
或 release-13 分支合并,这是额外的证据,这就是原因。该策略意味着发布标签无法相互访问,并且如果将一个发布标签合并到另一个发布标签,则可能会出现合并冲突。
那你该怎么办呢?
两个可能的选项是:
1. 从 main
分支(原来的主分支,不是你的分支 - 也许保持你的同步?)并继续变基到 main
直到你准备用您的代码做 其他事情。签出分支后,像这样重建分支:
git rebase --onto main llvmorg-12.0.0
后续变基将是常规的:git rebase main
2. 从较新的标签中重建您的分支,而不是合并到较新的标签中。签出分支后,像这样重建分支:
git rebase --onto llvmorg-13.0.0 llvmorg-12.0.0
我想了解以下(已尝试)git 合并的情况。
我有一个 llvm 的分支,其中 main
分支是上游的 llvmorg-12.0.0
标记,加上:
- 两个新文件。
- 现有上游文件的两个小改动。
我们可以通过这样做看到我在我的分支中触及的文件:
$ 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
标签。我已经 git fetch llvm
获取了所有上游的提交和标签。
让我们先创建一个分支来进行合并:
$ 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
冲突之一,文件中确实存在冲突标记(例如 libcxx/include/__support/openbsd/xlocale.h
):
...
<<<<<<< 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 diff --only-name
命令,我从未编辑过这些文件。
有什么进展吗?
用户error/misconception?我应该以不同的方式合并吗?
这是在 Debian 11 上使用最新的 git (2.33.0)。
如果标签 llvmorg-12.0.0
无法通过标签 llvmorg-13.0.0
访问,这可以解释。
换句话说,checkout tag 12,尝试合并tag 13,可能会冲突。如果您这样做(显然)与您的代码无关,这仅意味着该回购协议的维护者使用的分支策略不一定包括将已发布的标签合并回 main
。或者即使他们最终这样做了,他们也没有在这两个版本之间这样做。
您还可以使用此命令测试标签 12 是否可以从标签 13 访问(在 Git Bash 或 *nix shell 中):
git rev-list llvmorg-13.0.0 | grep `git rev-parse llvmorg-12.0.0`
命令的“rev-list”部分列出了所有可从标签 13 访问的提交,然后它会查看标签 12 的提交 ID 是否是其中之一。
如果没有任何输出,那么这就是正在发生的事情。
从您的合并输出中,您看到的带有 CONFLICT (add/add)
的行表明回购维护者从 release-12 分支中挑选了一些提交回到 main
或 release-13 分支合并,这是额外的证据,这就是原因。该策略意味着发布标签无法相互访问,并且如果将一个发布标签合并到另一个发布标签,则可能会出现合并冲突。
那你该怎么办呢?
两个可能的选项是:
1. 从 main
分支(原来的主分支,不是你的分支 - 也许保持你的同步?)并继续变基到 main
直到你准备用您的代码做 其他事情。签出分支后,像这样重建分支:
git rebase --onto main llvmorg-12.0.0
后续变基将是常规的:git rebase main
2. 从较新的标签中重建您的分支,而不是合并到较新的标签中。签出分支后,像这样重建分支:
git rebase --onto llvmorg-13.0.0 llvmorg-12.0.0