Git Submodule
I find myself interacting with submodules more and more, and never spent the time to properly understand how they work.
We call “superproject” the project that will contain the submodules.
Git submodules are used for when you have a git repository inside a git repository.
Resources
- https://git-scm.com/docs/git-submodule
- https://git-scm.com/book/en/v2/Git-Tools-Submodules
- https://medium.com/@porteneuve/mastering-git-submodules-34c65e940407
- https://www.atlassian.com/git/tutorials/git-submodule
Adding a new submodule
What if you wanted to put it inside a nested folder?
You can still do it, just make sure to
cd
inside the right directory first.
Removing a submodule
How Submodule Changes are detected
Git sees a submodule’s changes as a particular commit from that repository.
How are submodules built into git?
Git stores information about submodules in two places (Source):
.gitmodules
(Changes to this file are what get propagated to other repositories).git/config
(local changers. where git actually looks when performing most commands).
Just like. .gitignore
file, you will have a .gitsubmodules
file to maintain the list of submodules.
Periodically updating your submodules
Run the following:
git pull
git submodule update --init --recursive --remote
The git submodule update Command
The most common command you will need to use is git submodule update
, which performs the task of updating all of the local submodules you have in your copy of isaac_ros-dev. Technically, this command isn’t strictly necessary; everything it does can also be done by navigating to each individual submodule and checking out the latest version of the stable branch, but that process is very tedious when you have lots of submodules!
--init
: tells git to populate the folders of any new submodules that haven’t been initialized on your machine yet. Good for a fresh clone, but desn’t hurt to include this flag every time--recursive
: tells git to recursively update any submodules-of-submodules and so on--remote
: This flag tells git to fetch from the remote URL specified in the.gitmodules
file, and then checkout the latest commit. Note: Sometimes you will want to omit it!
Why you might not want to include
--rmeote
The reason you might not want to include this flag is because it will always checkout the ‘stable’ branch specified in .gitmodules; if you are currently working on a new feature branch that hasn’t been merged to main in one of your packages and you want to stay on that non-main branch, you will want to omit the —remote flag.
Cloning a project
Initialize your local configuration file (FIRST TIME)
git submodule init
What is the point of submodule init??
In this usage,
git submodule init
seems to do only one thing: populate.git/config
with information that is already in.gitmodules
. Why can’t you just combine it withgit submodule update
? Stackoverflow answer. Answer: there are use cases where you want s
Fetch all the data from that project and check out the appropriate commit listed in your superproject (--recursive
because submodules might contain submodules)
git submodule update --recursive
Another way
Another way to do it is by adding the
--recurse-submodules
flag, but I always forget. Ex:git clone --recurse-submodules https://github.com/chaconinc/MainProject
So the main question is, if the submodule gets updated, how do you update the superproject?
- Very easy, just commit/pull from inside the submodule, and then go to the parent git repository, and it will detect a change in terms of the commit hash
cd submodule
git pull
cd ..
git status # you will see a difference
git add .
git cm "bump submodules"