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