Replacing folders with submodules in Git
I recently ran across the following problem:
- Multiple people are developing on the same project, pushing commits into the same (e.g. GitHub) repo.
- Developer A is working, and commits locally.
- Developer B converts a folder into a Git submodule.
- Developer A tries to git pull… BOOM – unresolveable conflict, local repo is left in a mess.
The problem is that because Developer A has a local commit, this forces a merge. Git merge has absolutely no idea how to resolve a conflict between a folder and a submodule.
To fix this, divide the merge into two parts, so you can separate the actions of removing the folder, and adding the submodule:
- Figure out the SHA of the commit where the folder was removed; let’s call it abcdef (as far as I am aware you cannot remove a folder and add in the submodule in 1 commit, so there will always be 2 commits here).
- Reset your local repo back to HEAD
- Merge up to that commit: git merge.
- Merge the remaining commits
i.e.
git reset --hard HEAD
git merge abcdef
git mergeAlternatively, if only a few commits have been made and you are very lazy, you can do the following:
git merge origin~5 git merge origin~4 git merge origin~3 git merge origin~2 git merge origin~1 git merge
Note that if you don’t have local changes, this issue does not occur as the fast-forward mechanism just applies all the commits in sequence and everything is cool.
