Tags And Sub-modules - Git Series Part 6


Table of Contents

This is the final guide in the Git series. Here, we will be covering two more major features that Git has to offer: tags and sub-modules. If you have been following the previous guides, and other materials, you should have a clearer understanding of what Git is, what it does, how to use it best, and how to troubleshoot. Here is a list of many of the aspects we have covered in this series:

  • The basics: cloning a repo, committing changes, pushing to and pulling from a remote repository.
  • Specifying remote servers
  • Using branches to keep certain changes away from the master branch
  • Creating archives
  • Explored a few third-party GUI frontends available for Git
  • Stashing uncommitted changes away for later
  • Viewing commit history
  • Showing the differences between commits
  • Troubleshooting various issues including a merge conflict

​Now we will focus our attention on these two features.


Tags in git are references to a specific important commit in the branch history. Tags are often used to specify which commit is the last one before a project version is released. In other words, a release point is signified by a tag. There are two kinds of tags: lightweight and annotated.


Lightweight is the default option that the ‘git tag’ command uses when no other arguments are parsed. They don’t contain any extra information associated with them. They just reference a commit. To tag the most recent commit, run the tag command with the tag name.$ git tag v0.2-alpha​Parse the commit hash to tag a specific commit:

$ git tag v0.1-alpha <commit hash>

You can view information about the commit that a tag references simply by using the ‘–show’ parameter.$ git tag –show v0.1-alphaLightweight tags are best used either as a temporary label or to mark a minor milestone. Here is another example where I deleted a tag (‘-d’ parameter) because I forgot to specify the tag name before the commit hash. This resulted in a tag on the most recent commit with the hash as its name.

git tag 1

For more important points in history, there is the other type of tag.


Annotated tags contain more information about the tag. This includes the username and email of the person who created the tag and when, and also the tagging message. Creating an annotated tag requires an extra parameter: ‘-a’. It will open up a text editor so that a message about the tag can be entered. You can also quickly specify a message in the command using the ‘-m’ parameter like you do with ‘git commit’.

This saves you having to enter it in an editor. For more detailed information, it’s best to use the editor (no ‘-m’ parameter).

$ git tag -a v0.5-beta -m “Project in beta. 0.5” 

This will be stored as an object in the Git database. Other features of an annotated tag are that they are checksummed for integrity and digitally signed. Annotated tags are more suited for marking commits that are major milestones such as project releases.

Pushing Tags

In order to push tags onto the remote server, you will need to give the push command an extra parameter.​To push an individual tag to specify the tag name:

​$ git push <tag-name>

​To push all tags:$ git push –tags

git tag 2


Many Git projects rely on content from other projects to help provide the features they want for its users. Git has a tool that makes this so much easier using ‘git submodule’. If this feature didn’t exist, you would have to either bundle the libraries yourself into the repository or at least include the library in your code. Now the inclusion of the library in the code isn’t anywhere near as tedious as including the library in with your project.

It just means you need to let people know in a readme file what their system requires to be installed. Even then, there will be people who will have difficulty obtaining said libraries (believe me; I know from bitter experience). If you copy the dependencies into the repository, you would have to manage the updates yourself. Sometimes, you would have to update them whenever the time comes. Said dependencies can be quite large.

To solve these issues, you are able to include the libraries into your project by running ‘git submodule add <dependency-url>’. This will install the submodule into the current working directory by downloading the repository.

​$ git submodule add <dependency-url> 
git submodule add

The force parameter isn’t necessary unless you’re trying to add a path that is being ignored. You will need to commit the new ‘.gitmodules’ file, and the submodule folder itself to register any submodules.

Removing a Submodule

I made a mistake in declaring the submodule in the host. I should have specified the address of the actual remote server instead of the localhost address ( as the location of the submodule. There are two ways to proceed. Either open the .gitmodules folder and remove the reference to the submodule or, if there is only one submodule, delete the .gitmodules file. Have a look at the screenshot below.

git submodule remove

I used vim to open the ‘.git/config’ file to remove the submodule reference. I should also point out that this is the config file for your repository. As you can see, it includes the remote servers that were created earlier.

git config

​Then I removed the folder from the Git tracking system. I then checked what was going to be committed, removed the folder that had the module in it, and committed the changes.​I was free to add the module in again.

Cloning a Repo With Submodules

You have downloaded the source code of an open-source program in the form of a git repo. You’ve used ‘git clone’ to fetch the sources. There are libraries in the repository that the project depends upon, yet the folders are empty! More than likely, your repository has submodules that need to be fetched. There are two ways to do this. The simpler way is to give the ‘–recurse-submodules’ parameter when cloning the repository.

$ git clone –recurse-submodules <git-url>
git submodule clone

​If you have already cloned the repository, though, you must run these two commands to use the submodules:

$ git submodule init
$ git submodule update

These will allow you to clone the submodules into the repository. If you run ‘git log’ on the main repo, and then on the submodule, you will see two different commit histories.

git submodule separate histories

More Information

There is some documentation that also includes troubleshooting and more advanced techniques.


https://git-scm.com/book/en/v2/Git-Basics-Tagging​These are from the official Git site. Also, do have a look at the man pages for ‘git submodule’ and ‘git tag’.


After looking at these guides, you should have not only a basic understanding of how to use git for day to day use but also how to manage a repository. Also, handling issues, managing changes, branches, and modules, should be part of your skillset. There are numerous more resources on the Internet to peruse through. By all means, use those to learn even more about the capabilities of Git.​I encourage all of you to look at the Git documentation to learn what else you can do to take full advantage of using Git.

Learn GitUncategorizedtutorial