A headline feature of SourceTree 1.3 is the support for submodules (in Git) and subrepositories (in Mercurial). The terms may be different, but they refer to the same concept; that of nesting other repositories within the folder structure of your own repository. The most common reason for wanting to do this is that your project has dependencies on other code bases (libraries for example), and you want to track those from their original sources rather than duplicating the files within your own repository.
For the sake of brevity from here on I’ll use the term ‘submodule’ to mean ‘subrepository’ as well, unless I’m talking about a Mercurial-specific feature.
Adding a submodule to your project
Adding a new submodule to your project is simple, just right-click on a blank area of the sidebar and select ‘New Submodule’ (or select it from the Repository menu).
You’ll then be prompted to provide a source URL to clone the contents from, and the path within the current repository that this submodule will reside. Once the submodule has cloned, you’ll see it appear in the sidebar like this:
This tells you that your submodule is located in dependencies/sub1 and is currently on the ‘master’ branch. If you wanted to see more detail about the submodule, just double-click on it to open it in its own repository window, from which you can, if you like, make changes to it just like any other repository. Submodule entries can also have annotations to let you know if there are uncommitted changes in the submodule (ellipsis annotation, i.e. ‘…’), or incoming / outgoing changes (up/down arrow).
In this case you’ve just added the submodule, but it’s not actually committed yet. You’ll see in the file status view that a couple of entries have been staged:
In Mercurial, there will be a “.hgsub” file instead but the principle is the same. These uncommitted changes represent the addition of the submodule to your repository, and you must commit & push them as you would do with any other change. Once you’ve done this, anyone cloning the repository will also get the submodule, at the same commit.
Typical submodule tasks
Submodules are likely to be more static than your own main repository, but there are still several tasks related to them that you may want to do:
Change the submodule commit which your repository is tracking
Submodules are pinned at a given commit, so that you always get the expected version of the submodule contents. If there are new changes in the submodule which you want to use in your repository, all you have to do is open the submodule (double-click) and checkout/update to a different commit, either via pull, merge or just manually checking a commit out – just as you would do normally with any other repository. Once you have done this, return to the parent repository and you will see an uncommitted change on the submodule, which will show in the diff the change in tracked commit:
Again, you commit & push this change just like any other, after which point the submodule contents will be pinned at this new commit.
Commit / push changes to a submodule together with parent repository
If you have write access to the upstream submodule source (and if not, maybe you might fork it and change the submodule source, see below), you may sometimes update files in the submodule, and want to commit / push those changes at the same time as you commit / push changes to your parent repository.
Mercurial actually requires this, by default it automatically commits subrepository changes when you commit the parent, using the same commit message. However, that’s often not what you want – there’s a good chance you’ll want a different commit message for the submodule change. Luckily, SourceTree makes that really easy – when you try to commit the parent, if there are uncommitted changes in submodules you’ll get a prompt telling you so, like this:
From this dialog you can click the ‘Commit’ button next to the submodule and commit those changes with a message of your choosing, separate to the parent repo commit message. In Git, the ‘Skip’ button at the bottom is enabled so you can just leave the changes uncommitted if you like, but Mercurial doesn’t allow this.
Change the source URL for a submodule
A submodule definition includes the URL which people cloning the parent repository will retrieve the submodule content from. Sometimes, you might want to change this – a common example is if you were using a 3rd party library which you had only read-access to, but later decided to fork it and make your own changes. In this case, you’ll want to change the source URL to your fork for all future clones / updates. In SourceTree this is easy, just right-click on the submodule and select “Change Source URL”. You’ll need to commit and push the change as normal, but after that your fork will be the source for the submodule.
This has been a quick introduction to the submodule and subrepository support in SourceTree 1.3. It’s designed to make your life easier when managing projects with their dependencies and other project groupings, we hope you like it!