Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: Merging and Submodules

Lets say I have two branches in RepoX called BranchA and BranchB. RepoX also has a submodule called SubmoduleY.

BranchA has SubmoduleY at revision 'abc', BranchB has SubmoduleY at revision 'def'.

Say I want to merge BranchA into BranchB, but I want to leave BranchB's SubmoduleY pointing to its original revision of 'def'. I see a couple ways of doing this:

Method 1:

  1. Checkout BranchB.
  2. Move SubmoduleY to revision 'abc' to make the actual merge painless (we don't want to do any merging at the submodule level right now).
  3. Commit the new revision for SubmoduleY (we can't have it floating for the merge).
  4. Merge BranchA into BranchB. Resolve any conflicts.
  5. Move SubmoduleY back to revision 'def'.
  6. Commit the new revision for SubmoduleY.
  7. Push changes up to the main repo.

Method 2:

Same as method 1, but instead of doing step 6, rebase and get rid of the extra submodule commit from step 3.

Both seem to have annoying drawbacks:

Method 1 puts two extra commits into history.

Method 2 forgets any changes to do with submodule revisions because those commits get removed. Therefore, any merges later on will have to deal with some problems again.

Is there a better way?

like image 531
Ben Avatar asked Dec 07 '10 18:12

Ben


1 Answers

You could do a variation on your method 1, but do the commit that introduces the change to the submodule version (in your step 6) with --amend so that it changes the state of the submodule in the merge commit. In other words, this would be:

$ git checkout b
$ git merge a
Merge made by recursive.
 example.txt |    1 +
 sY          |    2 +-
 2 files changed, 2 insertions(+), 1 deletions(-)
 create mode 100644 example.txt
$ cd sY
$ git checkout def
[... you get the "detached HEAD" warning ...]
$ cd ..
$ git add sY
$ git commit --amend

Note that I didn't bother trying to avoid having the submodules at different versions before merging, as you suggested in your question. If there's a conflict, you can just choose to add the submodule at def to resolve it. If there isn't a conflict, the steps I mentioned above should work fine.

like image 70
Mark Longair Avatar answered Oct 15 '22 19:10

Mark Longair