Git Submodule Update
Halloween is here and we're back with Git Weekly #8, another piece on the spine-chilling git submodules. ??
Submodules are git's solution for embedding a repository into another. Some of the most often use cases for submodules are the following:
This article follows up on the intro piece I wrote earlier and assumes familiarity with the concept of submodules. If you're not familiar with submodules, please take a look at the prequel first.
Updating Submodules to the Latest Version
Submodules are like versioned third-party libraries. As an upgrade to the latest version of your dependency might break your code, so does an update to the latest version of the submodule.
To update your submodule to its latest version, do:
git submodule update
To review the commits that were added to the submodule, do:
git diff --submodule
After the code was tested against the new submodule version, commit the submodule by staging its path:
git add <the-submodule-path>
git commit -m "Update submodule to version XXX"
It's also important to have a meaningful commit message for it. If the submodule is not separately versioned, try to mention why the submodule was updated. E.g.
git commit -m "Update submodule to use Python 3.9"
Updating Submodule to a Specific Version
Now let's assume you want to upgrade (or downgrade) your submodule state to a specific version, e.g. a specific tag on the other repo or a specific branch, or even a specific commit.
Let's assume your submodule is under the path shared. Change your directory to this branch:
cd shared
If you have a terminal that shows the branches, it'll most likely show you a hash instead of a name:
~/the-repo/shared [(569d7ce...)]$
You can also run:
git branch
And the output will be something like:
* (HEAD detached at 569d7ce)
master
The "HEAD detached" state basically means that your current state of the submodule "has no name", i.e. no branch or tag points to that specific commit. If not, it's also good.
Now, all we want to do is to change the state of the submodule repo.
1. Update to a Specific Branch or Tag
To update your submodule to a specific branch or tag, simply switch to that branch or tag:
git switch specific-branch
Where specific-branch is the name of the branch you want to update your submodule to. This command is the same as:
git checkout specific-branch
We'll cover checkout vs switch in a later post.
2. Downgrade by One Commit
To go one commit back, one can checkout HEAD~1:
git checkout HEAD~1
3. Go to a Specific Commit
Now let's assume you want to change the state to a specific commit. First, find out the hash and checkout to it:
git checkout bfa784412503902f1d07edacb2e0e0954e2e221f
Get Back and Commit
Now that you're happy with the submodule state/version, you can get back to the original repo:
cd ..
To see what changes you made to the submodule, do:
git diff --submodule
It will list the commits that were added or removed, e.g.:
Submodule shared 43222e8..569d7ce (rewind):
< Add venv and pyc files to .gitignore
< Fix urllib3 version
This means the two mentioned commits were removed from the submodule (rewind).
Now, add the submodule and commit it:
git add shared
git commit -m "Rewind the commits"
Final Words