Submodules maintain a pointer to a specific commit in the external repository, while subtrees copy the entire subproject history (or a squashed version) into the parent repository.
Adding a New Subproject
- Submodule
- Subtree
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.Viewing a Diff of the Subproject
- Submodule
- Subtree
Cloning a Repository with a Subproject
- Submodule
- Subtree
To clone a repository along with its submodules:If you forgot
--recurse-submodules, you can clone and initialize all submodules:Adding
--recursive is only required if any submodule itself has submodules.Pulling in Superproject Updates
- Submodule
- Subtree
By default, the submodule repository is fetched, but not updated when you run
git pull in the superproject. You need to use git submodule update, or add the --recurse-submodules flag to pull:--init is required if the superproject added new submodules, and --recursive is needed if any submodule itself has submodules.If ever the superproject changes the URL of the submodule, a separate command is required:--recursive is only needed if any submodule itself has submodules.Changing Branches
- Submodule
- Subtree
By default, the submodule working tree is not updated to match the commit recorded in the superproject when changing branches. You need to use
git submodule update, or add the --recurse-submodules flag to switch:Pulling in Subproject Updates
- Submodule
- Subtree
git submodule update --remote command to specify which subproject to update.By default, git submodule update --remote will update the submodule to the latest commit on the main branch of the submodule remote.You can change the default branch for future calls with:Making Changes to a Subproject
- Submodule
- Subtree
Access the submodule directory and create a branch:Changes require two commits, one in the subproject repository and one in the parent repository. Don’t forget to push in both the submodule and the superproject!
Pushing Changes to the Subproject Repository
- Submodule
- Subtree
While in the submodule directory:Or while in the parent directory:
Helpful Configs for Submodules
These configuration settings can make working with submodules more convenient: Always show the submodule log when you diff:git status message:
push default to --recurse-submodules=on-demand:
clone) default to --recurse-submodules if they support the flag (this works for git pull since Git 2.15):