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>
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
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
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
Or in one go:
git submodule --init update
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
Do your changes and commit them to the submodule. Then push to the submodule's master branch:
git push origin master
Get back to the host repo and verify the changes you made to the submodule:
cd ..
git diff --submodule
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"
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.
Top comments (0)