How I Work on Four Git Branches at the Same Time
Git Worktrees Explained: What They Are and Why They Exist

If you've been using Git for a while, chances are you've gone through this.
You're deep into implementing a feature. Everything is going well. You have a few uncommitted changes, your development server is running, and you're finally in the zone.
Then someone pings you.
"Hey, can you quickly fix this production bug?"
Great.
Now your flow is interrupted.
You open the terminal and start the ritual.
git status
git add .
git stash
git checkout main
git pull
git checkout -b hotfix/login
You fix the bug.
Commit.
Push.
Now it's time to get back to your feature.
git checkout feature/report-generator
git stash pop
Hopefully nothing conflicts.
Hopefully you didn't forget what was in your stash.
Hopefully you don't accidentally commit the hotfix into your feature branch.
This isn't a Git problem. It's a workflow problem.
And it doesn't stop with production bugs.
Maybe you need to:
Review a teammate's pull request.
Experiment with another implementation.
Compare two branches.
Test something on the release branch.
Try a framework upgrade without affecting your current work.
Every time, you switch branches.
Every time, you break your flow.
Then I discovered Git Worktrees.
There Has To Be A Better Way
Imagine opening another VS Code window.
Another terminal.
Another branch.
Without touching your current one.
No stashing.
No switching.
No cloning the repository again.
Just another folder.
That's exactly what Git Worktrees allow you to do.
What Is Git Worktree?
Git Worktree allows you to have multiple branches checked out simultaneously.
Let's say your current repository looks like this.
Projects/
└── car360/
└── feature/report-generator
A production bug comes in.
Instead of switching branches, create another worktree.
git worktree add -b hotfix/login ../car360-hotfix main
Now your project structure becomes
Projects/
├── car360/
│ └── feature/report-generator
└── car360-hotfix/
└── hotfix/login
Open each folder in a separate VS Code window.
Run your development server inside each.
Each folder has its own working files, terminal, and Git status.
Yet they're all backed by the same repository.
Why Was Git Worktree Created?
Many developers think Git Worktrees exist only for fixing production bugs.
That's just one use case.
Modern software development isn't linear anymore.
You're rarely working on a single task from start to finish.
A typical day might involve
Building a new feature
Reviewing someone's pull request
Fixing a production issue
Testing against a release branch
Experimenting with a new architecture
Trying a framework upgrade
Without Worktrees, you're constantly switching contexts.
Git Worktrees were introduced to make parallel development easier.
Instead of moving between branches, each task gets its own workspace.
Under The Hood
At first glance, Worktrees look like another copy of your repository.
But that's not what actually happens.
Suppose your repository looks like this.
car360/
├── .git/
├── src/
├── package.json
└── ...
After creating a worktree
git worktree add -b hotfix/login ../car360-hotfix main
you get
car360/
├── .git/
├── src/
└── ...
car360-hotfix/
├── .git
├── src/
└── ...
Notice something?
The second repository doesn't even have a .git directory.
It has a tiny .git file.
Inside that file is something like
gitdir: /Users/ananthu/projects/car360/.git/worktrees/car360-hotfix
That file simply points back to the original repository.
Both worktrees share
commit history
object database
remotes
tags
branches
Each worktree has its own
working directory
HEAD
staging area
uncommitted changes
This is why changes in one worktree don't interfere with another.
Isn't This Just Cloning The Repository Twice?
This was my first question too.
At first glance, they look almost identical.
Projects/
├── car360/
└── car360-copy/
or
Projects/
├── car360/
└── car360-hotfix/
In both cases, you end up with two folders containing the same project.
So what's the difference?
Cloning the repository twice
When you clone a repository twice, you actually create two completely independent Git repositories.
Projects/
├── car360/
│ └── .git/
│
└── car360-copy/
└── .git/
Each clone has its own:
Git object database
References (
refs)Remote-tracking branches
Configuration
Hooks
Staging area (
index)Working directory
Although both clones start with the same commit history, each stores its own copy of that history and manages it independently.
If you run
git fetch
inside car360, only that repository gets updated.
car360-copy has no idea that new commits or branches exist until you fetch there as well.
They're completely separate repositories that just happen to have started from the same source.
Git Worktrees
Now let's look at a worktree.
Projects/
├── car360/
│ └── .git/
│
└── car360-hotfix/
└── .git
Notice something?
The second one doesn't even have a .git directory.
It has a tiny .git file.
If you open it, you'll see something similar to:
gitdir: /Users/ananthu/projects/car360/.git/worktrees/car360-hotfix
That file simply tells Git,
"My repository lives over there."
Both folders are connected to the same underlying Git repository.
They share:
Commit history
Object database
Branch references
Tags
Remotes
Hooks
Configuration
Each worktree only has its own:
Working directory
HEADStaging area (
index)Uncommitted changes
This means if you run
git fetch
from any worktree, every other worktree immediately sees the updated remote branches because they're all using the same Git metadata.
Why It's Surprisingly Optimised
The coolest part about Git Worktrees is how lightweight they are.
Git doesn't duplicate
commits
history
remotes
object database
tags
Only the working files are created again.
Imagine your repository history takes up 3 GB.
Your source code occupies another 200 MB.
Cloning twice might roughly consume
3.2 GB
+
3.2 GB
With Worktrees
3 GB
+
200 MB
+
200 MB
because the heavy Git database is shared.
You fetch once.
Everyone sees it.
You commit once.
The commit is stored in the same object database.
It's surprisingly efficient for something that feels like multiple repositories.
My Favourite Workflow
Nowadays my projects usually look something like this.
Projects/
├── car360/
│ └── feature/report-generator
│
├── car360-hotfix/
│ └── hotfix/login
│
├── car360-review/
└── teammate/payment-refactor
Each folder is opened in its own VS Code window.
Each has its own terminal.
Each can run
npm dev
simultaneously.
No switching branches.
No stashing.
No interrupting my flow.
Commands You'll Actually Use
Create a new worktree with a new branch
git worktree add -b feature/new-ui ../car360-new-ui
Create a worktree for an existing branch
git worktree add ../car360-review teammate/payment-refactor
List all worktrees
git worktree list
Remove a worktree
git worktree remove ../car360-review
Delete the branch if you no longer need it
git branch -d teammate/payment-refactor
Clean up stale worktree metadata
git worktree prune
A Few Things To Remember
The same branch cannot be checked out in two worktrees simultaneously.
Removing a worktree does not delete the branch.
Deleting the folder manually isn't recommended.
Always use
git worktree remove
to let Git clean everything up properly.
Final Thoughts
Git Worktrees have been part of Git for years.
Yet they're still one of the least talked-about features.
Once I started using them, I stopped thinking of Git as "one repository, one working directory."
Instead, each task got its own workspace.
I no longer stash my changes just because someone asked for a quick fix.
I no longer stop my development server to switch branches.
I simply open another folder and continue working.
Sometimes, the best productivity tools aren't new frameworks or AI assistants.
They're features that have quietly existed for years, waiting for someone to discover them.
Git Worktrees are one of those features.



