Mastering Git Worktree
Every developer knows the struggle: You're deep in the zone working on a new feature, numerous files are modified, the app is in a broken state... and suddenly, a critical bug report comes in. "Can you fix this ASAP?"
In the old days, you had two painful choices:
- Git Stash:
git stash save "wip feature"-> switch branch -> fix bug ->git stash pop. This is fast but risky. Resolving stash conflicts is a nightmare, and yournode_modulesor build artifacts might be out of sync. - Git Clone: Clone the entire repo again into a new folder. This is safe but slow, wastes disk space, and requires setting up your
envfiles and dependencies all over again.
Enter Git Worktree.
What is Git Worktree?
Introduced in Git 2.5, git worktree allows you to have multiple working directories attached to the same repository.
Imagine specific folders on your disk for specific branches:
/projects/my-app/main(checked out tomain)/projects/my-app/feature-x(checked out tofeature/x)/projects/my-app/hotfix(checked out tohotfix/login-bug)
All of them share the same .git object database. This means:
- Zero overhead: No need to re-download the repo history.
- Instant switching: Just
cdinto the folder. - Isolated environments: You can run different versions of the app, run tests, or install different dependencies simultaneously without them conflicting.
Basic Usage
1. Adding a Worktree
Let's say you are in your main project folder and want to start a hotfix without touching your current work.
# Syntax: git worktree add <path> <branch>
git worktree add ../my-app-hotfix master
This command creates a new folder ../my-app-hotfix at the same level as your current folder and checks out the master branch there.
If you want to create a new branch in that worktree:
git worktree add -b fix/urgent-bug ../my-app-hotfix master
2. Listing Worktrees
To see all your active worktrees:
git worktree list
Output:
/Users/dev/projects/my-app (main)
/Users/dev/projects/my-app-hotfix (fix/urgent-bug)
3. Removing a Worktree
Once you are done with the hotfix and have merged it:
# 1. Delete the folder
rm -rf ../my-app-hotfix
# 2. Tell git to clean up metadata
git worktree prune
Alternatively, you can use git worktree remove ../my-app-hotfix, which handles both steps safely (it warns you if you have uncommitted changes).
Pro Workflow: The "Bare Repository" Method
For the ultimate clean setup, many senior developers use a Bare Repository.
Standard cloning puts the .git folder inside your working directory. A bare clone is the .git folder. This allows you to treat all branches as equal worktrees, keeping your project directory clean.
Step 1: Clone as Bare
Instead of a normal clone, create a directory for your project and clone with --bare.
mkdir my-super-app
cd my-super-app
git clone --bare [email protected]:username/repo.git .bare
Now, create a special .git file that points to this bare directory so standard git commands work in the root.
echo "gitdir: ./.bare" > .git
Note: You need to configure the bare repo to fetch remote branches correctly:
cd .bare
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
cd ..
Step 2: Create Worktrees
Now, never work in the root. Create a worktree for everything.
# Create main branch folder
git worktree add main
# Create feature folder
git worktree add -b feature/login features/login
Step 3: Enjoy the Structure
Your folder structure now looks like this:
my-super-app/
βββ .bare/ # The Git database (do not touch)
βββ .git # Pointer file
βββ main/ # The main branch code
βββ features/
β βββ login/ # The feature branch code
βββ hotfixes/
βββ urgent/ # The hotfix branch code
Now you can run the backend in main/ while developing the frontend in features/login/ simultaneously!
Best Practices & Pitfalls
- Don't checkout the same branch twice: Git won't let you checkout
mainin two different worktrees simultaneously to prevent state corruption. - Dependency Management: Remember that each worktree is a fresh checkout. You will need to run
npm install(or equivalent) in each new worktree. This is a good thingβit ensures your dependencies are exactly what that branch expects. - Local Config: Since they share the
.gitfolder, your global.git/configis shared. However, files ignored by git (like.env) need to be copied to each worktree.
Conclusion
git worktree is a powerful tool that, once adopted, makes it hard to go back. It encourages smaller, more focused workspaces and enables true multitasking without the headache of context switching. Give it a try on your next complex feature!