Sometimes you might need to nest a git-project inside another git-project. The right strategy is to use submodules in this case.
How git submodules work
- Each submodule is a own git repository
- Once you commit changes in a submodule, the parent repository can link the new
sha
as its reference - You need to take care manually that your git submodules are up-to-date and changes in the submodules are linked in the parent repository
Add a submodule
Here is how you add a nested project inside your parent project
$ git submodule add <nested-repository-url>
git status
will now show you the following:
new file: .gitmodules
new file: nested_project
nested_project
will point to the specific sha
of the nested project. It will never add the files inside the submodule.
Clone a project with submodule
New team members can check out the the parent project and the nested project with one command:
git clone --recursive <parent-repository-url>
If you forgot to add the --recursive
-flag, you have to do the following to pull the code for the submodule:
git submodule init
git submodule update
Update a submodule and reference it to the parent-repository
cd ~/Project/parent-repository/submodules/nested_project
touch example.txt
git add .
git commit -m 'New file'
git push
cd ~/Project/parent-repository
git add submodules/nested_project
git commit -m 'Use new version of nested_project'
git push
Checkout the parent-repository and all its submodules with the correct referenced sha
s
cd ~/Project/parent-repository
git submodule update
Update the parent-repository module to the most current version of the submodules
In general submodules are in a detached head
-state. Nevertheless you can update the reference for all to master.
git submodule foreach --recursive git fetch
git submodule foreach --recursive git checkout master
You now will see a message like:
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: ~/Project/parent-repository/submodules/nested_project (new commits)
Submodules changed but not updated
no changes added to commit (use "git add" and/or "git commit -a")
Reference the new sha
in the the parent-repository
and push:
git add submodules/nested_project
git commit -m 'Update the submodules`
git push
Advanced configuration
It is helpful to set the global git config git config status.submodulesummary 1
. This will add a short summary of the commits in the git submodules.
Example:
$ git config status.submodulesummary 1
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: .gitmodules
modified: DbConnector (new commits)
Submodules changed but not updated:
* DbConnector c3f01dc...c87d55d (4):
> catch non-null terminated lines