Replacing folders with submodules in Git

I recently ran across the following problem:

  1. Multiple people are developing on the same project, pushing commits into the same (e.g. GitHub) repo.
  2. Developer A is working, and commits locally.
  3. Developer B converts a folder into a Git submodule.
  4. 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 merge

Alternatively, 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.

You must be logged in to post a comment.