what causes submodule conflicts in git, and how should they be resolved?
We are using submodules and we are new to git.
We often see merge conflicts for the submodules themselves, no files are conflicted, just the submodule. There are multiple versions listed in the output of git submodule summary
. We resolve them by running git add <submodule>
in the superproject.
Your local submodule and the remote submodule have diverged.
git checkout --theirs submodulename
or for your version:
git checkout --ours submodulename
and then commit the changes with git add and commit the changes.
Note: Your shell may add a trailing slash to the submodulename if you tabcomplete, since it is also a subdirectory. If so, you need to delete it or you'll get:
error: pathspec 'submodulename/' did not match any file(s) known to git.
Both file conflicts and submodule conflicts occur when your current branch and the branch-you-want-to-merge-into have diverged.
It merely means an ambiguous situation exists -- you could legitimately want either to "win" in any given case. So, while it may seem "annoying", they merely highlight your rich options to specify what you want (and you must specify what you want). (And, all that programmers do every day is merely to specify detail.)
It seems like the git-add-the-submodule-on-the-superproject should have worked. However, you also had the option to git-checkout-on-the-superproject right away. This is mentioned in this link (resolving submodule conflicts), which talks about the difference between file conflicts and summodule conflicts, and how to resolve them:
http://pacific.mpi-cbg.de/wiki/index.php/Git_Conflicts
At least Git 2.38 (Q3 2022) provides more detailed help messages while merging submodules, especially in case of merge conflict.
See commit 565577e, commit 34ce504, commit a5834b7 (18 Aug 2022) by Elijah Newren (newren
).
See commit 4057523 (04 Aug 2022) by Calvin Wan (CalvinWan0101
).
(Merged by Junio C Hamano -- gitster
-- in commit df3c129, 25 Aug 2022)
submodule merge
: update conflict error messageSigned-off-by: Calvin Wan
When attempting to merge in a superproject with conflicting submodule pointers that cannot be fast-forwarded or trivially resolved, the merge fails and Git prints an error message that accurately describes the failure, but does not provide steps for the user to resolve the error.
Git is left in a conflicted state, which requires the user to:
- merge submodules or update submodules to an already existing commit that reflects the merge
- add submodules changes to the superproject
- finish merging superproject
These steps are non-obvious for newer submodule users to figure out based on the error message and neither
git submodule status
(man) norgit status
(man) provide any useful pointers.Update error message to provide steps to resolve submodule merge conflict.
Although the message is long, it also has the id of the submodule commit that needs to be merged, which could be useful information for the user.
Additionally, 5 merge failures that resulted in an early return have been updated to reflect the status of the merge.
- Null merge base (null o):
CONFLICT_SUBMODULE_NULL_MERGE_BASE
added as a new conflict type and will print updated error message.- Null merge side a (null a): BUG(). See discussion
- Null merge side b (null b): BUG(). See for discussion
- Submodule not checked out: added NEEDSWORK bit
- Submodule commits not present: added NEEDSWORK bit The errors with a NEEDSWORK bit deserve a more detailed explanation of how to resolve them.
See here for more context.
You now have a line of advice to resolve a merge conflict in a submodule.
The first argument is the submodulename, and the second argument is the abbreviated id of the commit that needs to be merged.
For example:
go to submodule (mysubmodule), and either merge commit abc1234
or update to an existing commit which has merged those changes
Also, new message:
Recursive merging with submodules currently only supports trivial cases.
Please manually handle the merging of each conflicted submodule.
This can be accomplished with the following steps:
sub1:
- come back to superproject and run:"
git add sub1
to record the above merge or update"
- resolve any other conflicts in the superproject
- commit the resulting index in the superproject
精彩评论