Your project (`Parent Repo`) needs to include code from another repository (`Library Repo`). How do you manage this relationship? Let's explore two common Git strategies.
Parent Repo
P1
←
P2
main
Library Repo
L1
←
L2
main
Key Point: You want to use the code from `Library Repo` inside `Parent Repo`, but you also want to be able to easily update the library code as it changes.
2
The `submodule` Approach
A submodule is a link to a specific commit in another repository. Your parent repo doesn't contain the library's code, only a pointer to it.
Parent Repo
P1
←
lib @ L1
main
Library Repo
L1
←
L2
main
How it works: The `Parent Repo` stores a reference to commit `L1`. When someone clones your project, they must run `git submodule update --init` to actually download the library code. Updating the library is a manual process of changing this pointer.
3
The `subtree` Approach
A subtree copies the files and history from the library directly into your parent repo. The two projects become one, but Git knows how to merge updates.
Parent Repo History
P1
←
L1'
←
L2'
←
P2
main
How it works: The commits `L1'` and `L2'` are copies of the library's history, now living inside the `Parent Repo`. When someone clones your project, they get the library code automatically. There are no extra steps.
4
Pros & Cons Comparison
Submodules and subtrees are two very different ways to solve the same problem. Choosing the right one depends on your team's workflow and needs.
Submodules (Linking)
Pro: Keeps parent repo small and clean.
Pro: Clear separation between project and dependency.
Con: More complex workflow for everyone. Requires extra commands (`submodule update`).
Con: Can be confusing, especially with detached HEAD states within the submodule.
Subtrees (Copying)
Pro: Simple for contributors. Just `git clone` and it works.
Pro: No new commands for collaborators to learn.
Con: Parent repo history becomes larger and more complex.
Con: Pushing changes back to the original library is more difficult.
Rule of Thumb: Use Submodules when you need strict versioning and a clean separation, and your team is comfortable with the workflow. Use Subtrees when you want simplicity for collaborators and don't plan to contribute back to the dependency often.