Adding a New Subproject
Submodule
git submodule add https://github.com/githubtraining/example-submodule
git commit -m "adding new submodule"
The submodule add
command adds a new file called .gitmodules
along with a subdirectory containing the files from example-submodule
. Both are added to your index (staging area) and you simply need to commit them. The submodule’s history remains independent of the parent project.
Subtree
git subtree add --prefix=example-submodule https://github.com/githubtraining/example-submodule master --squash
The subtree command adds a subdirectory containing the files from example-submodule
. The most common practice is to use the --squash
option to combine the subproject’s history into a single commit, which is then grafted onto the existing tree of the parent project. You can omit the --squash
option to maintain all of the history from the designated branch of the subproject.
Viewing a Diff of the Subproject
Submodule
To view a diff of the submodule:
git diff --cached example-submodule
git diff --cached --submodule example-submodule
Subtree
No special command required
Cloning a Repository with a Subproject
Submodule
Anyone who clones will need to:
git clone --recursive URL
Anyone who already has a local copy of the repo will need to:
git submodule update --init
Subtree
No special command required
Pulling in Subproject Updates
Submodule
git submodule update --remote
If you have more than one submodule, you can add the name of the submodule to the end of the command to specify which subproject to update.
By default, this will update the submodule and check out to the default branch of the submodule remote.
You can change the default branch with:
git config -f .gitmodules submodule.example-submodule.branch other-branch
Subtree
git subtree pull --prefix=example-submodule https://github.com/githubtraining/example-submodule master --squash
You can shorten the command by adding the subtree URL as a remote:
git remote add sub-remote https://github.com/githubtraining/example-submodule.git
You can add/pull from other refs by replacing master with the desired ref (e.g. stable, v1.0).
Making Changes to a Subproject
In most cases, it is considered best practice to make changes in the subproject repository and pull them in to the parent project. When this is not practical, follow these instructions:Submodule
Access the submodule directory and create a branch:
cd example-submodule
git checkout -b branch-name master
Changes require two commits, one in the subproject repository and one in the parent repository.
Subtree
No special command required, changes will be committed on the parent project branch.
It is possible to create commits mixing changes to the subproject and the parent project, but this is generally discouraged.
Pushing Changes to the Subproject Repository
Submodule
While in the submodule directory:
git push
Or while in the parent directory:
git push --recurse-submodules=on-demand
Subtree
git subtree push --prefix= example-submodule https://github.com/githubtraining/example-submodule master
Helpful Configs for Submodules
Always show the submodule log when you diff:
git config --global diff.submodule log
Show a short summary of submodule changes in your status message:
git config status.submoduleSummary true
See the diffs in all of your submodules:
git config alias.sdiff "git diff; git submodule foreach 'git diff'"