Git Submodules

Mohammad-Ali A'RÂBI - Sep 19 - - Dev Community

While developing a project, you often want to have another project within it. Some common cases for such a need are the following:

  • A shared repo containing formatting style guides or build tools
  • A third-party library
  • A repo that you want to Dockerize in your current project

In these cases, you can use git submodules.

Creating a Submodule

To create a submodule within your git repo, you need to run the following command:

git submodule add <url> <directory>
Enter fullscreen mode Exit fullscreen mode

Here <url> is a placeholder for the other repo's URL and <directory> for the directory name in which you want to have your submodule. For example, the following command creates a submodule from the GitHub repo django-twitter-clone and stores it inside the directory django-twitter-clone:

git submodule add git@github.com:aerabi/django-twitter-clone
git django-twitter-clone
Enter fullscreen mode Exit fullscreen mode

After this command is executed, a file with the name of .gitattributes is created under the repo's root with the following content:

[submodule "django-twitter-clone"]
   path = django-twitter-clone
   url = git@github.com:aerabi/django-twitter-clone.git
Enter fullscreen mode Exit fullscreen mode

For each additional submodule, a new entry is recorded in this file.

Cloning a Project with Submodules

Let's assume you want to clone a repo with a submodule. After a usual git clone, the path containing the submodule will still be empty. To populate it, you need to run the following commands additionally:

git submodule init
git submodule update
Enter fullscreen mode Exit fullscreen mode

Or in one go:

git submodule --init update
Enter fullscreen mode Exit fullscreen mode

Contributing to a Submodule

A submodule is its own git repo. You have different branches on the main repo and its submodule.

Let's assume your submodule exists under the path shared and you can and want to commit directly to its master. To contribute to the submodule, first, go to that path and change the branch:

cd share
git checkout master
git pull
Enter fullscreen mode Exit fullscreen mode

Do your changes and commit them to the submodule. Then push to the submodule's master branch:

git push origin master
Enter fullscreen mode Exit fullscreen mode

Get back to the host repo and verify the changes you made to the submodule:

cd ..
git diff --submodule
Enter fullscreen mode Exit fullscreen mode

Git should show you a list of commits added to the submodule since the last version of it you had on your branch. If you're happy, add the submodule and commit the changes:

git add shared
git commit -m "Update the submodule"
Enter fullscreen mode Exit fullscreen mode

In summary, this is what we did here:

  • Make some changes to the "other" repo
  • Push the changes to master
  • Move the "submodule pointer" to point to the latest version of master, on the main repo
  • Commit the new pointer value in the main repo

Each one of these acts can be done independently.

  • One could clone the "other" repo independently and make some changes to it.
  • One can change the master on the "other" repo by accepting and merging a pull request.
  • One can only update a submodule that has been contributed to by other people by changing the branch on it and pulling the latest changes.

Summary

Dealing with git submodules is not trivial. It might take years for one to become comfortable with submodules. This is the main reason many people prefer not to use them and look for alternatives. I would say, they are very useful and powerful, only some guidance and education might be necessary for people not exposed to them.

There are still more to the submodules. I'll do a follow-up article on the same topic later.

  • Subscribe to my Medium publishes to get notified when a new Git Weekly issue is published.
  • Follow me on Twitter for weekly articles and daily tweets on git.
. . . . . . . . . . . . . . . . .
Terabox Video Player