I have two branches A
and B
. Both contain a submodule (in the folder sub
), however at different commits (which do not fast-forward from one to another).
A B | / BASE
I've checked out A
, but the submodule isn't initialized yet. Now I merge B
and I get a conflict on the submodule.
$ git status Unmerged paths: (use "git add <file>..." to mark resolution) both modified: sub
Issuing git checkout --ours sub
does nothing (if the submodule is initialized it works, also git checkout-index -f --stage=2 -- sub
does not work). git add sub
causes the error error: pathspec 'sub' did not match any file(s) known to git.
.
$ git diff sub diff --cc sub index 533da4e,ab2af77..0000000 --- a/sub +++ b/sub @@@ -1,1 -1,1 +1,1 @@@ - Subproject commit 533da4ea00703f4ad6d5518e1ce81d20261c40c0 -Subproject commit ab2af775ec467ebb328a7374653f247920f258f3 ++Subproject commit 0000000000000000000000000000000000000000
git submodule init -- sub
does nothing. Also git submodule update --init --force -- sub
does not work: Skipping unmerged submodule sub
.
So, how can I resolve this submodule conflict (without aborting the merge and retry after initializing the submodule)?
If you already cloned the project and forgot --recurse-submodules , you can combine the git submodule init and git submodule update steps by running git submodule update --init . To also initialize, fetch and checkout any nested submodules, you can use the foolproof git submodule update --init --recursive .
You can fix it by: either committing or undoing the changes/evolutions within each of your submodules, before going back to the parent repo (where the diff shouldn't report "dirty" files anymore). To undo all changes to your submodule just cd into the root directory of your submodule and do git checkout .
What makes your situation kind of annoying is that git won't let you initialize an unmerged submodule, so the ordinary advice of just setting the submodule to the state you want within the submodule then running git add
won't work. What you can do is to update the index directly, without going through the working tree.
One way to update the index is with git reset
. If you know a commit in which the submodule is in a state you want, you can use that. For example, any of the following might be what you want:
git reset master -- sub git reset master@{upstream} -- sub git reset HEAD -- sub git reset MERGE_HEAD -- sub
The other option is to update the index directly using the plumbing command git update-index
. To do that, you need to know that an object of type gitlink (i.e., directory entry in a parent repository that points to a submodule) is 0160000. There's no way to figure that out from first principles, but you can figure it out from git ls-files -s
or the following reference (see "1110 (gitlink)" under 4-bit object type): https://github.com/gitster/git/blob/master/Documentation/technical/index-format.txt
To use that approach, figure out the hash you want to set the submodule to, then run, e.g.:
git update-index --cacheinfo 0160000,533da4ea00703f4ad6d5518e1ce81d20261c40c0,sub
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With