Skip to content, Skip to search


Git submodule tutorial

4,502 bytes added, 13:48, 5 February 2009
no edit summary
~/fiji$ git push
== Resolving Submodule Conflicts ==
When merging and rebasing fiji, you are likely to end up having to fix conflicts in the versions of submodules. These next two sections are intended to help you to resolve these conflicts.
=== Submodule Conflicts while Merging ===
You are most likely to have submodule conflicts while merging when you run "git merge" or "git pull" (which effectively runs "git fetch" followed by "git merge").
FIXME: finish writing this section the next time I have one of these conflicts in front of me...
=== Submodule Conflicts while Rebasing ===
Conflicts in submodule versions while you're rebasing are slightly different. For example, I am in the following situation:
o---o----o----o----o master
A----B----C-----D----E----F server
And I want to rebase server onto master, by doing the following:
git checkout server
git rebase -i master
The "-i" option means that I am first presented with a list of commits to port onto master, named A, B, C, D, E and F in the above diagram. After possibly making some changes (there may be some commits that you don't actually want to include in the rebased version) the rebasing begins. The first error I get is the following:
Automatic cherry-pick failed. After resolving the conflicts,
mark the corrected paths with 'git add <paths>', and
run 'git rebase --continue'
Could not apply 1f7b713... Various changes to make the server work better
If you get a message saying you have to resolve conflicts that means that "git status" will tell you what they are. In this case I get:
VIB: needs merge
# Not currently on any branch.
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
# modified:
# deleted: server-init.d-script
# modified: staged-plugins/VIB_.config
# Changed but not updated:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
# modified: ImageJA
# modified: TrakEM2
# unmerged: VIB
# modified: java/linux
# modified: java/linux-amd64
# deleted: mpicbg
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
[... various irrelevant untracked files ...]
In this case, there's only one problem: versions of the VIB submodule conflict.
Let's say that the situation now corresponds to the following diagram:
A'---B' HEAD
o---o----o----o----o master
A----B----C-----D----E----F server ORIG_HEAD
First, it's important to see what change in version that commit is trying to make, so take the partial SHA1 sum from the line "Could not apply" above and pass it to git show, so "git show 1f7b713". This shows the patch introduced by that commit, but we're only looking out for the lines relating to the VIB submodule, which are:
diff --git a/VIB b/VIB
index c03c2cc..b6d78c8 160000
--- a/VIB
+++ b/VIB
@@ -1 +1 @@
-Subproject commit c03c2cc7d150087d91879012e1b312e3b2957733
+Subproject commit b6d78c8c390072d89059956d4d3596114c6301f1
Now just to check that we understand what's going on, run three versions of the diff command. First, show differences between the the last successful commit in this rebase and the working tree version:
git diff --base VIB
* Unmerged path VIB
diff --git a/VIB b/VIB
index c03c2cc..764f65b 160000
--- a/VIB
+++ b/VIB
@@ -1 +1 @@
-Subproject commit c03c2cc7d150087d91879012e1b312e3b2957733
+Subproject commit 764f65baee6af310cac4879a52805d7bffcd4dd0
That shows us that the version in the old commit is as we expect (good!) The version in the "+" line is what's in our working tree, or what you'll see if you do "( cd VIB && git show HEAD )". So, in this case I think it's a good idea to switch VIB to be the version that the commit we're cherry-picking tried to introduce, i.e. b6d78c8c390:
( cd VIB && git checkout b6d78c8c390 )
git add VIB
Now we should be able to continue, with "git rebase --continue"
==== A note on "ours" and "theirs" ====
If you're using "git diff --theirs" and "git diff --ours" while rebasing then you may get confused. Essentially:
* "git diff --theirs" shows the differences between the "server" branch and the working tree.
* "git diff --ours" shows the differences between the "master" or "upstream" branch and the working tree.
This is probably the opposite way round from what you expect from resolving conflicts while merging :)
Emailconfirmed, incoming, administrator, uploaders