It often happens that while working on one project, you need to use another project from within it. Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other. Now that I’am working on The HomeKit SDK I need to use several Repository’s to Compile the needed Binary files.
Why Submodules
Here’s an example. Suppose you’re developing a website and creating Atom feeds. Instead of writing your own Atom-generating code, you decide to use a library. You’re likely to have to either include this code from a shared library like a CPAN install or Ruby gem, or copy the source code into your own project tree. The issue with including the library is that it’s difficult to customize the library in any way and often more difficult to deploy it, because you need to make sure every client has that library available. The issue with copying the code into your own project is that any custom changes you make are difficult to merge when upstream changes become available.
Git addresses this issue using submodules. Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate.
Starting with Submodules
We’ll walk through developing a simple project that has been split up into a main project and a few sub-projects. First make a new repository on Github and the clone it to your computer.
Git Clone --recursive https://github.com/YOUR_GIT_NAME/YOUR_GIT_REPOSITORY.git
Now let’s start by adding an existing Git repository as a submodule of the repository that we’re working on. To add a new submodule you use the git submodule add command with the absolute or relative URL of the project you would like to start tracking. In this example, we’ll add a fictive library called “Repository_Example
” Type:
git submodule add https://github.com/AchimPieters/Repository_Example
Then it will clone the repository to YOUR_GIT_REPOSITORY
Cloning into 'YOUR_GIT_REPOSITORY'... Remote: Counting objects: 11, done. Remote: Compressing objects: 100% (10/10), done. Remote: Total 11 (delta 0), reused 11 (delta 0) Unpacking objects: 100% (11/11), done. Checking connectivity... done.
By default, submodules will add the subproject into a directory named the same as the repository, in this case “Repository_Example
”. You can add a different path at the end of the command if you want it to go elsewhere.
If you run Git status
at this point, you’ll notice a few things.
Git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD ..." to unstage) new file: .gitmodules new file: Repository_Example
First you should notice the new .gitmodules file. This is a configuration file that stores the mapping between the project’s URL and the local subdirectory you’ve pulled it into:
[submodule "Repository_Example"] path = Repository_Example url = https://github.com/AchimPieters/Repository_Example
If you have multiple submodules, you’ll have multiple entries in this file. It’s important to note that this file is version-controlled with your other files, like your .gitignore file. It’s pushed and pulled with the rest of your project. This is how other people who clone this project know where to get the submodule projects from. That’s it Now you can add submodules to your repository! when you are ready you only need to push it to your GitHub.