I'd like to understand what's going on with the following (attempted) git merge.
I have a fork of llvm where the main
branch is upstream's llvmorg-12.0.0
tag, plus:
- Two new files.
- Two small changes to existing upstream files.
We can see the files I've touched in my branch by doing this:
$ 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
And here's what my main
branch looks like in tig
:
Now I want to sync to the latest llvm release into my branch, i.e. the llvmorg-13.0.0
tag. I've already done git fetch llvm
to get all of upstream's commits and tags.
Let's start by making a branch to do the merge in:
$ git co -b sync-llvm13
Switched to a new branch 'sync-llvm13'
Now let's do the merge:
$ 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
This comes as a surprise. There are loads of files marked as conflicting, but which I've never touched.
The conflicts are a mix of add/add
, rename/delete
and content
.
Looking at one of the content
conflicts there are indeed conflict markers in the file (e.g. 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
...
(So this rules out line endings as a cause)
I'm confused. As shown above with the git diff --only-name
command, I've never edited these files.
What's gong on?
User error/misconception? Should I have merged a different way?
This is using the latest git (2.33.0) on Debian 11.
CodePudding user response:
This could be explained if tag llvmorg-12.0.0
is not reachable by tag llvmorg-13.0.0
.
In other words, checkout tag 12, and try to merge in tag 13, and you may get conflicts. If you do it (obviously) has nothing to do with your code, it just means that that the branching strategy the maintainers of that repo use doesn't necessarily include merging released tags back into main
. Or if they eventually do, they didn't do it between those two releases.
You could also test if tag 12 is reachable from tag 13 with this command (in Git Bash or a *nix shell):
git rev-list llvmorg-13.0.0 | grep `git rev-parse llvmorg-12.0.0`
The "rev-list" part of the command lists all commits reachable from tag 13, and then it greps to see if tag 12's commit ID is one of them.
If that outputs nothing, then this is exactly what is happening.
From your merge output, the lines you see with CONFLICT (add/add)
suggests that the repo maintainers cherry-picked some commits from the release-12 branch back into main
or the release-13 branch instead of merging, which is additional proof this is the reason. That strategy means that release tags are not reachable from each other, and that merge conflicts could arise if you merge one release tag into another.
So what should you do?
Two possible options are:
1. Branch off of main
(original main, not your fork- maybe keep yours synced?) and keep rebasing onto main
until you're ready to do something else with your code. With your branch checked out, rebuild your branch like this:
git rebase --onto main llvmorg-12.0.0
Subsequent rebases would be regular: git rebase main
2. Rebuild your branch off of the newer tag instead of merging in the newer tag. With your branch checked out, rebuild your branch like this:
git rebase --onto llvmorg-13.0.0 llvmorg-12.0.0