Share the contents of a repository with one or more other repositories as an external subtree or sub-repository in the other host repositories.
- Update external_repo with changes in host_repo subtree
- Update host_repo subtree with changes in external_repo
- Switch between branches of subtree
Add External as a Remote
Add the external_repo URL to local Git as a remote repository that commands can refer to using the --prefix flag.
git remote add -f <name> <url>
<name>
-> use the same name of the external_repo, NOT as an explicit path<url>
-> the external_repo's HTTPS or SSH address
Example
git remote add -f appservice ssh.dev.azure.com:v3/company/group/appservice
Add Subtree to Parent
Merge the external_repo as a subtree into the host_repo with a merge commit that does not include the external_repo's commit history.
git subtree add --prefix=<prefix> <repository> <ref> --squash
<prefix>
- the local directory name, which is the name used for the external_repo's url added with "remote" command<repository>
- the same name as the prefix (yep, same as prefix)<ref>
- the external_repo's branch name
Example
git subtree add --prefix appservice appservice main --squash
Push this host_repo commit to origin as usual
Push host subtree changes to external repo
Change to root of host_repo
cd ../host_repo
Add, commit as usual
git commit -a -m 'changing subtree from parent'
Push host_repo subtree changes to origin as usual (including subtree)
git push origin feature/make_this_feature
Push host_repo subtree changes to remote/external
git subtree push --prefix <prefix> <repository> <external_branch>
<prefix>
-> is name used for the external repo's url added with "remote" command<repository>
-> is the local git repo name of the external repo (NOT beginning with a ./)<ref>
-> is the external repo branch name
Example
git subtree push --prefix appservice appservice main
Change to root of external_repo
cd ../external_repo
Pull subtree changes
git pull origin master
(or just git pull
)
Pull external changes to host repo subtree
Change to root of external_repo
cd ../external_repo
Add, commit as usual
git commit -a -m 'changing subtree from external'
Push external_repo changes to origin main branch as usual
git push origin main
Change to the host_repo/subtree directory (even though you're specifying the prefix)
cd ../host_repo/subtree
Merge changes made to external_repo into the host_repo with a merge commit that does not include the external_repo's commit history
git subtree pull --prefix=<host_repo_name> external_repo_name --squash
Example
git subtree pull --prefix=appservice appservice --squash
Add a merge commit comment like 'pulling in updates to subtree from external_repo'.
Switch between branches of subtree
git rm -r appservice; git commit -m 'switching subtree branches';
git subtree add --prefix appservice appservice feature/update_feature --squash
Manage remote
git remote remove appservice
Sanity notes
- External is usually used as a reference library.
- Have both host and external as local repos.
- Do push/pull only on established main/develop type branches.
- Pull external repo changes from subtree directory of parent repo!!
References
Git subtree tutorial and demo - video
Mastering git subtrees
Learn git subtree
When to use git subtree
How to use git subtree to manage multiple project repositories