By Mikael Nordberg

In our current project we’re using some shared libraries that we have developed as open source. These libraries are something that we upgrade on a regularly basis, so referencing the built assembly would add some pain when, for example, a bug is found in a library.
What we really want is to include the shared projects source code and be able to add all changes back to their own repositories. Git submodules lets us do just that.
This is the structure of our main_project
/
/lib
/lib/nhibernate
/lib/log4net
/lib/.....
/src
/src/main_project
/src/main_project_classlibrary
/src/.....

From main_project all assemblies are referenced from the /lib folder.

Our shared projects are configured to look for it’s references in ../lib which will be equal to /lib for the main_project.
To add a shared project to our main_project we do:
git submodule add git@github.com/frontwalker/NullReference.Data.git src/NullReference.Data
This will add the NullReference.Data project into /src/NullReference.Data folder. But what if NullReference.Data is updated with some breaking changes? Do we need to update and recompile our main_project? Only if we want the new features!
The submodule that is added to our main project is added with the exact version that the project was in at the given time when it was added as a submodule. So if NullReference.Data was added at version 1.23 it will stay at that version in main_project until we decide to update it even if NullReference.Data it self is updated from another project.

Cloning a tree with submodules

To clone the main_project you do it as you normally would with the “git clone” command. But when opening one of the folders for a submodule you will find out that they contain no files at all. Git doesn’t automatically fetch all your submodules when you clone a project, so you need to “init” and “update” for the submodules before you can use them.
git submodule init
git submodule update

You only need to do this once or if someone adds another submodule.
Alot of information about the command is found in the documentation and I also found this blog post from “mathie” very helpful.

You can check out our NullReference libraries on GitHub.