How to update submodules in git
Git is a great tool, but very confusing for anyone who comes from a SVN or CVS background. Most of what it does is straightforward (if you learn it from the right place – I strongly recommend Pro Git for anyone who wants to learn git), but using submodules is a bit confusing. I’ve found that Chris Jean’s Blog and the chapter on submodules in Pro Git both explain different parts of it well (I recommend reading them in that order), but it still takes a little effort to work out what you should do when you want to apply updates from a submodule’s own repository to the version that you have in your own project. Here is a summary of my understanding.
Submodules are always headless when they are comitted: you are only committing a tag, not the code that is in the submodule folder.
There are two scenarios for updating a submodule (in all of the following, I assume that you have already initialised and updated your submodule):
- You want to update the submodule locally and push the update to the repository:
- Change your submodule from a headless branch (the state that it will be in after running git submodule update) onto a working branch (eg. origin/master), using git checkout
- Update the submodule using git pull from inside the submodule’s directory
- Change to the parent directory of the submodule and add the submodule directory to the staging area using git add
- Commit using git commit
- If you’re using a remote repository, now use git push
Note that this will commit the submodule tag that was pushed most recently, not the code that’s actually in the submodule directory, therefore any code in the submodule that was not pushed will be lost (as explained in Pro Git)
- Someone else updates the submodule and you want to pull the change from the repository:
- Use git submodule update to pull the changes from the repository. This will overwrite your local version of the submodule with a headless branch (if you’d like to now edit it, use the procedure above).
It’s also worth remembering that the submodule directory acts like a git repo in it’s own right, so changes made and commands run inside that directory will affect the submodule whereas changes and commands used outside will affect the parent project instead.