How to use submodules
If you would like to set up a repository that makes use of some code or other content that is contained in another repository on OpenVT or a different git server, the Git submodule structure is a handy tool that allows automatically synchronising and pulling the content from the secondary repository.
In the following, a few hints how to get started with submodules and how to perform simple submodule operations -- for more information, please refer to the Git manual.
Getting started
- Start a Project on OpenVT, let's say the name is my_awesome_project (that one will be called 'main repository' in the following). You would like to include some other repository in there, let's say that one is called the_other_awesome_project (that one can be located on OpenVT or any other git server; we will refer to it as the 'submodule repository').
- Make a clone of the main repository on your computer:
git clone <cloning_link_for_my_awesome_project>
- Now browse into the folder of the clone and link to the submodule repository as submodule:
git submodule add <cloning_link_for_other_awesome_project>
That will eventually prompt you for your access credentials to the other project and clone the contents into a subdirectory of the same name.
- If you clone a repository which already contains a submodule, cloning the main repository creates an empty folder for the submodule. You have to separately pull the submodules. After cloning, browse into the folder of the clone and do:
git submodule init
git submodule update
If the submodule structure has been created successfully, you will see in the main repository a folder labeled 'name_of_submodule_repository @ commit_SHA' (pointing to a certain commit of the submodule repository identified by the hash). If you browse to that folder in your clone, you will find the contents of the submodule repository (according to the version of that commit).
Updating the submodule(s) to latest commit
- As pointed out above, a submodule always points to a certain commit of the submodule repository. This does not change if you pull the main repository. In order to update also the submodules to the latest commit of each, you can either just successively browse to each submodule folder and pull the branch of your choice (in many cases, that will be 'origin master'):
git pull <remote branch name>
- Or, you can browse to the main repository and simultaneously pull all submodules:
git pull --recurse-submodules
git submodule update --remote
Controlling to which commit a submodule is pointing
A submodule is always tied to one particular commit of the repository it refers to, as specified by the commit hash. This can be used, e.g., to make sure to use a version of the submodule content that the content of the main repository has been tested with, independently of awailable later updates of the submodule repository. It is possible to change the commit that the submodule is pointing to:
- Find the commit hash of the desired commit (e.g. by looking at the commit history in the submodule repository on the OpenVT platform or via git log in the submodule folder)
- browse into the submodule folder
- checkout the desired commit:
git checkout <commit hash>
- browse back to the main folder and push the changes in the submodule:
git add .
git commit -m 'commit message, e.g. update submodule (name_of_submodule)'
git push <remote branch name (origin master in most cases)>
Pushing changes to submodules
If you have done changes to the content of a submodule, they are not automatically pushed by pushing the main repository. This is convenient if you use the submodule structure only as passive way to include content from a repository that you cannot write to yourself (but of which you would like to always have the latest version). In that case, any accidental changes to the submodule can simply reverted by doing in the submodule folder
git reset --hard
This will discard all changes and reset the submodule to the commit it is pointing to.
In case you would also like to do modifications to the submodule content and push your changes to the submodule repository, you have to first checkout a certain branch of the submodule repository (e.g., master):
git checkout <branch_name>
Then you can add, commit and push your changes:
git add .
git commit -m 'place your commit message here'
git push <remote branch name (origin master in most cases)>
After pushing to the submodule, you should still push the update on the main repository, in order to make the submodule point to the latest commit (the one you have just pushed): browse to the main repository and do
git add .
git commit -m 'commit message, e.g. update submodule (name_of_submodule)'
git push <remote branch name (e.g., origin master)>
This push of the main repository has not done any changes to the submodules (which have already been pushed in the last step) -- it has merely updated the submodule structure. On the OpenVT platform, you will see that the commit hash given with the submodule has changed to that of the latest version.