Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merging after directory got turned into submodule

I find that working with git submodules, I often encounter problems merging between commits which do contain a given submodules and those which represent the same code as a normal directory. Small reproducing example:

# Create one project, to be used as a subproject later on
git init a
cd a
echo aaa > aa
git add -A
git commit -m a1
cd ..

# Create a second project, containing a as a normal directory initially
git init b
cd b
mkdir a b
echo aaa > a/aa
echo bbb > b/bb
git add -A
git commit -m b1

# Replace directory with submodule
git rm -r a
git submodule add ../a a
git commit -m b2

# Try to create branch from the pre-submodule state of affairs
git checkout -b branch HEAD^

This already gives an error:

error: The following untracked working tree files would be overwritten by checkout:
    a/aa
Please move or remove them before you can switch branches.
Aborting

In order to avoid the error, I deinitialize all submodules first:

# Create feature brach starting at version without submodule
git submodule deinit .
git checkout -b branch HEAD^
echo abc > b/bb
git commit -a -m b3

As you can see, the feature branch is completely unrelated to the submodule, modifying a different set of files. Which makes this whole problem particularly annoying.

# Try to merge the feature branch
git checkout master
git merge branch

This fails again, with an error message I don't fully understand:

CONFLICT (file/directory): There is a directory with name a in branch. Adding a as a~HEAD
Automatic merge failed; fix conflicts and then commit the result.

I get the same error if I do a git submodule update --init before the git merge branch. I don't see any a~HEAD anywhere, neither in my directory tree nor in the output from git status, which reads like this:

On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")

Changes to be committed:

    modified:   b/bb

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    added by us:     a

If I do git add a as suggested, I get another error:

error: unable to index file a
fatal: updating files failed

If I do git submodules update --init just before the merge, then I can do git add a successfully. But if I forget to do so, and then try doing that after the merge, I receive this error message:

Submodule 'a' (…/a) registered for path 'a'
Skipping unmerged submodule a

How do I recover from this situation? Something other than git merge --abort, since I'd like to use it for things like git rebase as well, and since in some scenarios (don't know how to reproduce) I couldn't even abort the merge cleanly, and had to do a hard reset instead.

How can I avoid it in the first place? Is there some magic setting which makes git do the right thing with submodules vs. directories during merges, so that I don't have to manually post-process a merge which only modifies files unrelated to the submodules?

like image 953
MvG Avatar asked Aug 04 '15 23:08

MvG


People also ask

Do submodules update automatically?

Submodules are very static and only track specific commits. Submodules do not track git refs or branches and are not automatically updated when the host repository is updated. When adding a submodule to a repository a new . gitmodules file will be created.


1 Answers

No you should not add a, the merge is not supposed to change it. What you should run is

git reset a

So you ignore the "chage" for a.

PS: apparently git merely checks existense of a directory, so if you

git submodule deinit a
rmdir a

before merging, it will succeed. Not sure if this is what you want.

like image 142
max630 Avatar answered Sep 30 '22 04:09

max630