Submodules & Worktrees — Advanced Repo Management
AdvancedSubmodules embed one Git repository inside another at a pinned commit — for shared libraries or dependencies. Worktrees let you check out multiple branches simultaneously in separate directories from one repository.
Overview
As projects grow, two advanced features become relevant. Submodules solve the problem of depending on a specific version of another repository — a common library, a forked dependency, firmware in a hardware project. They are powerful but notoriously confusing; the key is understanding that a submodule is a pointer to a specific commit in another repo, not a copy of the code. Worktrees solve the problem of needing to work on two branches simultaneously — checking out a hotfix branch while in the middle of a feature, without stashing or cluttering your working directory.
Git Submodules
A submodule is a reference from your repo to a specific commit in another repo. Your repo tracks the submodule's commit hash — not its content. This pins your dependency to an exact version.
# Add a submodule
git submodule add https://github.com/org/shared-ui.git libs/shared-ui
# .gitmodules is created/updated:
# [submodule "libs/shared-ui"]
# path = libs/shared-ui
# url = https://github.com/org/shared-ui.git
# Clone a repo WITH submodules (two ways)
git clone --recurse-submodules https://github.com/org/project.git
# Or in two steps:
git clone https://github.com/org/project.git
git submodule update --init --recursive
# Update submodule to latest remote (then commit the pointer)
cd libs/shared-ui
git fetch && git checkout main && git pull
cd ../..
git add libs/shared-ui
git commit -m "chore: update shared-ui to latest main"
# Check status of all submodules
git submodule statusGit Worktrees
Worktrees let you check out multiple branches at once in separate directories — all sharing the same .git directory and object store. Perfect for hotfixing while mid-feature.
// Without worktrees (current workflow):
// 1. Stash your feature work
// 2. Switch to main, create hotfix branch
// 3. Fix and push
// 4. Switch back, pop stash
// → Context switching, stash conflicts
// With worktrees:
// ├── project/ ↠main worktree (feature/cart branch)
// │ â””── .git/
// â””── project-hotfix/ ↠linked worktree (hotfix/v2.1 branch)
// No .git/ — shares the one in project/
# Create a new worktree for the hotfix
git worktree add ../project-hotfix hotfix/login-null-pointer
# Work in the second directory — completely independent
cd ../project-hotfix
git status # on hotfix/login-null-pointer
# ... fix, commit, push ...
# List all worktrees
git worktree list
# /Users/akshay/project a3f8c12 [feature/cart]
# /Users/akshay/project-hotfix 9d2e441 [hotfix/login-null-pointer]
# Remove the worktree when done
git worktree remove ../project-hotfixKey Points to Remember
- 1A submodule is a pointer (commit hash) to another repo — git clone --recurse-submodules fetches both
- 2Updating a submodule requires committing the updated pointer in the parent repo
- 3Worktrees allow multiple branches checked out simultaneously in separate directories
- 4All worktrees share one .git/ directory — no duplication of the object store
- 5Prefer worktrees over stash when you need to switch context for more than a few minutes
Interview Questions
Sign in to ask AriaWhat is a Git submodule? When would you use it?
What is a Git worktree and how does it differ from cloning the repo again?
What happens when you clone a repo with submodules without --recurse-submodules?
Ask Aria about Submodules & Worktrees — Advanced Repo Management
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.