Git submodule update on branch switch
Asked by Jason Pecho:

It appears that the default behaviour of SourceTree is to run git submodule update --init right after git checkout when switching branches. Is there an option to turn this off? I checked the preferences and couldn't find an option for this. I have written a post-checkout hook that sets the proper branch for my submodules. However, it runs before the git submodule update call, thus detaching the head again. If there is such thing as a post-submodule-update hook, I could move my hook but it doesn't appear that there is, so the only work around is to disable this feature in SourceTree.

Thanks!


Answers:
author: KieranA
body: Hi Jason,

The two repositories are loosely connected, but the parent repository needs to refer to a specific commit for a submodule at a certain point in time in order to maintain not only consistency between the two but for compatibility reasons the submodule will be dependent on the parent repository as to what needs checking out. Basically, they synchronise with one another. This is called commit tracking.

To ignore commit tracking means you're ignoring the submodule's related commit to the parent commit. If a change in the submodule causes the parent repository to break then it's better practice to rely on a specific submodule SHA.

Git does allow you to checkout the HEAD of the submodule, but Mercurial doesn't even allow this option. Basically, we can add the option to SourceTree (only for Git though) but we've avoided doing so because of the dangers involved. In your case, however, you may be aware of the changes in the submodule and actually need the HEAD for a specific SHA in your parent repository.

The best option would be to have a Custom Action within SourceTree that you manually run after you checkout your repository which will update the submodule to the HEAD commit. We would recommend a post-checkout action but then your submodule would always be at its HEAD commit regardless of what you checkout (which deviates from the purpose of submodule commit tracking)

Hope that helps, feel free to make further questions/comments

comments: author: Jason Pecho
body: This makes sense. But we're using our submodules in a slightly different way. Our submodules are usually being actively developed alongside the super project. The submodule has a specific set of branches for the super project. The reason for that is the submodule is a common set of functions and classes that can be used on any project but each project has the opportunity to add stuff to said common functions and classes. This way, we can merge, cherry pick, etc, changes from a project back into the master for the subodule and distribute it to other projects or future projects if we so choose. Since we're using the git flow branching structure, we'd like to be able to apply that same branching structure to the submodule, expecially for releases so we can make sure the submodule changes only in very specific ways in preperation for a release. Because this means there may be many branches in the submodule, I'd like to automatically checkout the branch in the submodule so our engineers don't accidentally checkout the wrong branch or work in a detached HEAD state. If you have suggestions for the workflow, I'd love to hear them as well.

Since we are often switching branches, because of the git flow structure, making sure the engineer is on the right branch in the submodule is of upmost importance.


author: KieranA
body: Are you guys using Git or Mercurial?


author: Jason Pecho
body: We are using git


author: Jason Pecho
body: Any other thoughts on this?


author: KieranA
body: OK, we can add the option to checkout the HEAD of the submodule in Git, but this would probably be an opt-in option in the preferences. I've created an issue here: <https://jira.atlassian.com/browse/SRCTREE-1520>

If you check out the docs you'll see that Git tracks the actual commit of the submodule, so when you commit from the parent repository, if you've made a commit in the submodule then it'll just use that SHA in the submodule file that you commit to the parent repository.

So, the opt-in pref could probably allow for a checkout of a particular commit or just default to the HEAD. I'd say we'll add a bit of flexibility into it, but from what you've said I'm assuming you only want the HEAD commit of the submodule in all cases?


author: Jason Pecho
body: Checking out the HEAD would by default checkout the branch that contians the commit the HEAD points to?


author: KieranA
body: Yes, sorry, my point is that the option should be much like other checking out options whereby you can specify either a specific SHA or just the HEAD, we may as well leverage the flexibility that Git provides in the event that perhaps you want to checkout a previous commit rather than the HEAD every time.


author: Jason Pecho
body: Agreed! Thanks for the communication. How do feature adds work? When can we expect to see this in SourceTree? Thanks again!


Tags: hook

submodule