How do I manage conflicts with git submodules?

2019-01-30 13:16发布

问题:

I have a git superproject that references several submodules and I am trying to lock down a workflow for the rest of the my project members to work within.

For this question, lets say my superproject is called supery and the submodule is called subby. (Then is a simplification of what I'm trying to do...I'm not actually using the branches for versions, but I thought it would be easiest to lay out as a question.)

My master branch of supery has the tag v1.0 of the git project subby referenced as a submodule. The branch of supery called one.one and changed the reference of the submodule to point to the tag v1.1 of subby.

I can work within each of these branches without a hitch, but if I try to update the one.one branch with changes from the master branch I receive some conflicts and I don't how to resolve them.

Basically after running a git pull . master while in the subby branch, it looks like it creates additional submodules.

Before the pull/merge, I get the desired response from git submodule from the one.one branch:

$ git checkout master
$ git submodule
qw3rty...321e subby (v1.0)
$ git checkout one.one
$ git submodule
asdfgh...456d subby (v1.1)

But after the pull, it adds additional submodules when I run git submodule:

$ git pull . master
Auto-merged schema
CONFLICT (submodule): Merge conflict in subby - needs qu3rty...321e
Automatic merge failed; fix conflicts and then commit the results.

$ git submodule
qw3rty...321e subby (v1.0)
asdfgh...456d subby (v1.1)
zxcvbn...7890 subby (v1.1~1)

How do I delete/ignore the unwanted submodule references and commit my conflicts and changes? Or is there a parameter I can use with my original git pull that will ignore my submodules?

回答1:

I have not seen that exact error before. But I have a guess about the trouble you are encountering. It looks like because the master and one.one branches of supery contain different refs for the subby submodule, when you merge changes from master git does not know which ref - v1.0 or v1.1 - should be kept and tracked by the one.one branch of supery.

If that is the case, then you need to select the ref that you want and commit that change to resolve the conflict. Which is exactly what you are doing with the reset command.

This is a tricky aspect of tracking different versions of a submodule in different branches of your project. But the submodule ref is just like any other component of your project. If the two different branches continue to track the same respective submodule refs after successive merges, then git should be able to work out the pattern without raising merge conflicts in future merges. On the other hand you if switch submodule refs frequently you may have to put up with a lot of conflict resolving.



回答2:

Well, its not technically managing conflicts with submodules (ie: keep this but not that), but I found a way to continue working...and all I had to do was pay attention to my git status output and reset the submodules:

git reset HEAD subby
git commit

That would reset the submodule to the pre-pull commit. Which in this case is exactly what I wanted. And in other cases where I need the changes applied to the submodule, I'll handle those with the standard submodule workflows (checkout master, pull down the desired tag, etc).



回答3:

I struggled a bit with the answers on this question and didn't have much luck with the answers in a similar SO post either. So this is what worked for me - bearing in mind that in my case, the submodule was maintained by a different team, so the conflict came from different submodule versions in master and my local branch of the project I was working on:

  1. Run git status - make a note of the submodule folder with conflicts
  2. Reset the submodule to the version that was last committed in the current branch:

    git reset HEAD path/to/submodule

  3. At this point, you have a conflict-free version of your submodule which you can now update to the latest version in the submodule's repository:

    cd path/to/submodule
    git submodule foreach git pull origin SUBMODULE-BRANCH-NAME
  4. And now you can commit that and get back to work.



回答4:

First, find the hash you want to your submodule to reference. then run

~/supery/subby $ git co hashpointerhere
~/supery/subby $ cd ../
~/supery $ git add subby
~/supery $ git commit -m 'updated subby reference'

that has worked for me to get my submodule to the correct hash reference and continue on with my work without getting any further conflicts.



回答5:

I had this problem with git rebase -i origin/master to a branch. I wanted to take master's version of the submodule ref, so I simply did:

git reset master path/to/submodule

and then

git rebase --continue

That solved the problem for me.



回答6:

Got help from this discussion. In my case the

git reset HEAD subby
git commit

worked for me :)



回答7:

Well In my parent directory I see:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Unmerged paths:
(use "git reset HEAD <file>..." to unstage)
(use "git add <file>..." to mark resolution)

So I just did this

git reset HEAD linux