Sometimes we want to put a directory or part of our project in a different repo. An example I can think of is a creation of themes for a particular web framework. I first saw this pattern when I learned Hugo Framework, where themes are added as a submodule into the main Hugo repo initialized. There are 2 ways we can deal with subrepositories:
Making a submodule
A submodule is a way to integrate another repository into the main repo without integrating its history and branches. The submodule history remains independent from the main repo.
$ git submodule add repository-name
To pull submodule updates into your repo. Use the submodule update command
$ git submodule update --remote
To push changes into the submodule, run git push
inside the submodule directory.
Making a subtree
A subtree is essentially integrating another repository into the main repo, including its history. To initialize a subtree, run the following command:
$ git subtree add --prefix=subdirectory/path/ repository-name master
To prevent the repository history from polluting your master repo, you can add --squash
prefix to pull all changes in one single commit.
If there is an update to the subtree, you can pull the changes using git subtree pull
$ git subtree pull --prefix=subdirectory/path/ repository-name master
You can add --squash
again if you don’t want to see the subtree commit history in your git repo history. Now you can push into the main repository.
If there are changes in the subdirectory as you work on the project, you can push those changes into the subrepo history and its remote with a single push.
$ git subtree push --prefix=subdirectory/path/ repository-name master
In this way, you’ll keep things in the subdirectory separate from the main project.
Which one to use?
I have personally used submodule for some of my projects, but you can see this github cheat sheet to compare and find one that is suitable for your project.