what causes submodule conflicts in git, and how should they be resolved?
Asked Answered
C

3

13

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.
But today we had a developer lose a commit of the submodule when she resolved the conflict in this manner.
Does running a git add choose the remote version? Shouldn't the contents of the submodule get merged? If she made changes in the submodule and committed them (which I see), then why would that commit disappear after she ran the pull and resolved the conflict?

Clavius answered 14/7, 2011 at 21:22 Comment(0)
P
11

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

Paschasia answered 18/7, 2011 at 18:40 Comment(3)
I think the link is not currently working. WebArchive to the rescue: web.archive.org/web/20100925080451/http://pacific.mpi-cbg.de/…Salmanazar
git checkout --theirs <submodule> or for your version: git checkout --ours <submodule>Florrie
Clarification to your initial statement: The potential conflicted files/submodules must have both changed in both diverged paths. Simply a branch diverging does not mean you will get conflicts.Idden
F
12

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.
Florrie answered 19/5, 2014 at 11:28 Comment(1)
This isn't working for me: upstream changes the module, and while merging in their changes I tried 'git checkout --theirs ios_src' but in 'git diff origin/dev_ios .' I still see my local oid marked '-dirty' and the new one not marked dirty. I was expecting to see the my local line to be the new oid with a '-dirty' mark. Committing also leaves me with my oid. Going into the modules and explicitly checking the root out, then adding it works, but that's tedious.Befriend
P
11

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

Paschasia answered 18/7, 2011 at 18:40 Comment(3)
I think the link is not currently working. WebArchive to the rescue: web.archive.org/web/20100925080451/http://pacific.mpi-cbg.de/…Salmanazar
git checkout --theirs <submodule> or for your version: git checkout --ours <submodule>Florrie
Clarification to your initial statement: The potential conflicted files/submodules must have both changed in both diverged paths. Simply a branch diverging does not mean you will get conflicts.Idden
I
0

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 message

Signed-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:

  1. merge submodules or update submodules to an already existing commit that reflects the merge
  2. add submodules changes to the superproject
  3. 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) nor git 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.

  1. Null merge base (null o): CONFLICT_SUBMODULE_NULL_MERGE_BASE added as a new conflict type and will print updated error message.
  2. Null merge side a (null a): BUG(). See discussion
  3. Null merge side b (null b): BUG(). See for discussion
  4. Submodule not checked out: added NEEDSWORK bit
  5. 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

With Git 2.45 (Q2 2024), batch 4, when a merge conflicted at a submodule, merge-ort backend used to unconditionally give a lengthy message to suggest how to resolve it.
Now the message can be squelched as an advice message.

See commit b9e55be (26 Feb 2024) by Philippe Blain (phil-blain).
(Merged by Junio C Hamano -- gitster -- in commit 661f379, 05 Mar 2024)

merge-ort: turn submodule conflict suggestions into an advice

Signed-off-by: Philippe Blain

Add a new advice type 'submoduleMergeConflict' for the error message shown when a non-trivial submodule conflict is encountered, which was added in 4057523 ("submodule merge: update conflict error message", 2022-08-04, Git v2.38.0-rc0 -- merge listed in batch #15).
That commit mentions making this message an advice as possible future work.
The message can now be disabled with the advice mechanism.

Update the tests as the expected message now appears on stderr instead of stdout.

git config now includes in its man page:

submoduleMergeConflict

Advice shown when a non-trivial submodule merge conflict is encountered.

Isola answered 10/9, 2022 at 13:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.