Imagine you are working on a project and would like to include someone else’s work. Luckily, that work is already on Github. Submodule helps you with that.
Before we get started let me say this: Git submodule is a great tool but generally has a bad reputation.That reputation is hard earned. Why? Git submodule do not really incorporate the submodule into your repository. Think of it more like a pointer to a repository and a specific commit. This means that if you clone a repository with a submodule, you need to say
git submodule init and
git submodule update.
This also means that if you make changes in that submodule and you want others to see those changes, you have to push those changes in the submodule back to the source of that submodule. (If you can’t do this, on Github you can just fork the repository and point your submodule to your fork.)
Git subtree is an alternative but it is not yet available on all distributions and slightly more complicated. So you have to be a bit careful in using submodule. But let’s get started.
Create a new repository, and add a file readme.md to it.
$ mkdir myrepo $ cd myrepo $ git init $ git add readme.md $ git commit -m "Initial commit."
Now, let’s assume that you found a library that you’d like to include. I just went to Github and found this little gem: It makes nice html presentations. So, I added it in the following way:
$ git submodule add https://github.com/bartaz/impress.js.git impress_lib
You will now have a folder
$ git status will give you:
# On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # new file: .gitmodules # new file: converter
Commit this (everything has already been staged):
$ git commit -m "Added submodule impress_lib for nice presentations"
Next, let’s pick a specific tag in that library.
$ cd impress_lib $ git checkout tags/0.5.3
Go back to your base folder and let your repository know that you want this commit:
$ cd .. $ git add impress_lib $ git commit -m "impress_lib: Using version 0.5.3 now."
Essentially, whenever you are in the submodule folder (i.e.
impress_lib/) you can work on it as though it were a normal git repository. When you want to let your main repository know of these changes, move to the root of the main repository and commit
impress_lib. In your root repository
impress_lib behaves just like a file and a diff will show the commit hash.
Let’s push our repository to Github:
$ git push
If someone else pulls or clones the repository they have to do:
$ git submodule init $ git submodule update
But back to your own repository. Before I said that you can use checkout and then notify your repository about this change by committing that you changed to a specific commit. What if you want to change something in the library?
Easy as pie: Go into the library, do your changes and commit them.
$ cd impress_lib
Make some changes…
$ git commit -am "Smoother transition effects." $ git push
For safety, you should push these changes, otherwise other people using your repository won’t have access to this code.
Back to our root directory and informing the repository that we want to use that new commit.
$ cd .. $ git add impress_lib $ git commit -m "Use improved transition effects in impress_lib."
This concludes this short overview of git submodule. I hope you gained some insight into git submodules and will have a chance to use it sometime soon.