What Are Git Worktrees?

What Are Git Worktrees?

A comprehensive, zero-prior-knowledge exploration of how Git lets you have several branches checked out as real, separate folders at once — without cloning your repository over and over again.

Imagine a woodworking shop with a single workbench. If you’re building a chair but suddenly need to quickly fix a wobbly table someone else is waiting on, you have to clear your entire chair project off the bench, set the table down, fix it, clear it off again, and reassemble your chair project exactly where you left off — every single time you switch tasks. Now imagine that same shop had several separate, fully equipped workbenches instead: your half-finished chair stays exactly as it is on one bench, while you calmly walk over to a second, completely separate bench to fix the table, without disturbing your chair project at all. Git worktrees bring exactly this second setup to your codebase — letting you have more than one branch checked out, as real, separate folders on disk, at the very same time. In this guide, we’ll build this idea up completely from zero — what a worktree actually is, why it exists, exactly how Git manages several of them safely from one underlying repository, and how teams use this capability in real, practical workflows.

1Core Concepts: What a Git Worktree Actually Is

Before any internal mechanics, let’s build a precise, plain-language definition.

What it is: A worktree is a separate, real folder on your computer’s disk containing the actual, checked-out files of one specific branch, linked back to a single, shared underlying Git repository. Using Git’s worktree feature, you can create several of these folders at once — each one showing a different branch, fully checked out and ready to work in — all connected to and sharing the exact same history, without needing several independent copies of the repository.

Why it exists: Ordinarily, a Git repository has exactly one working directory, showing exactly one branch’s files checked out at any given moment — switching branches replaces what’s on disk with that branch’s version. This is perfectly fine for most everyday work, but it becomes a real friction point the moment you need to work on, or even just quickly glance at, more than one branch at the same time. Worktrees exist specifically to remove that friction, letting several branches exist as real, simultaneously usable folders, without the overhead of maintaining several entirely separate repository clones.

Where it’s used: Worktrees are commonly used for quickly handling an urgent bug fix without disturbing in-progress feature work, running a slow test suite against one branch while continuing to develop on another, and comparing behavior between two different branches side by side, among other practical multi-branch scenarios.

Everyday Analogy

Think of a worktree like having several browser windows open to different tabs of the same website, all logged into the same account, all seeing the same underlying data — versus needing to log out and log back in every time you want to look at a different page. Each window shows something different, but they’re all fundamentally connected to, and drawing from, the exact same underlying account. Worktrees give your branches this same kind of simultaneous, independently visible existence, all sharing one underlying repository.

Practical example: A developer deep in the middle of a complex, half-finished feature suddenly needs to fix an urgent bug on the main branch. Instead of stashing their in-progress feature work, switching branches, fixing the bug, and switching back, they create a second worktree — a separate folder showing the main branch, fully checked out — fix the bug there, all while their original feature-branch folder remains completely untouched and exactly as they left it.

2The Problem & Motivation Behind Worktrees

Like every feature in Git’s design, worktrees exist because of a real, repeated, practical limitation that came before them.

Before worktrees existed, a developer facing the “urgent bug fix while mid-feature” scenario from Chapter 1 had essentially two imperfect options. The first was to temporarily set aside their in-progress, uncommitted changes using a stashing mechanism, switch branches, handle the urgent matter, switch back, and restore their stashed work — a process that works, but adds real friction and risk, especially if anything unexpected interrupts that careful sequence partway through. The second option was to clone the entire repository a second time into a completely separate folder — functional, but wasteful, since it duplicates the repository’s entire object database on disk, and requires separately keeping two full copies in sync with any new shared history.

Worktrees were introduced specifically to offer a genuinely better third option: multiple, simultaneous working folders, each showing a different branch, all sharing one single, common repository underneath — avoiding both the disruption of constant switching and the wastefulness of full, separate clones.

i
Key Insight

A worktree is not a copy of the repository — it’s a separate checkout, sharing the exact same underlying object database, covered further in Chapter 3. This is the crucial distinction that makes worktrees efficient: the potentially large history of commits, blobs, and trees is stored only once, no matter how many separate working folders you have checked out from it.

The core problem worktrees solve: how do you let a developer work on, or simply inspect, more than one branch at the same time, as genuinely separate, simultaneously usable folders on disk, without either disrupting in-progress work through constant switching, or wastefully duplicating an entire repository’s full history for every additional folder needed?

3Architecture & Components: How Worktrees Are Structured

Understanding exactly what’s shared between worktrees, and what’s kept separate for each one, clarifies both their efficiency and their safety.
Shared

Object Database

The full history of commits, trees, and blobs, covered in a related guide on content hashing, lives in exactly one place, shared by every worktree.

Shared

Refs & Branches

Branch names and their pointers are part of the same shared repository, visible and usable from any worktree.

Separate

Working Directory

Each worktree has its own, independent folder on disk containing that specific branch’s actual, checked-out files.

Separate

Index (Staging Area)

Each worktree maintains its own separate staging area, so preparing a commit in one worktree doesn’t interfere with another’s in-progress staged changes.

This split — one shared object database and set of branches, but a genuinely separate working directory and staging area per worktree — is exactly what allows several worktrees to coexist safely: they can’t accidentally interfere with each other’s uncommitted, in-progress work, while still fully sharing and benefiting from the same underlying commit history the instant something is actually committed.

1
OBJECT DATABASE
shared by every worktree
N
WORKING DIRECTORIES
can exist simultaneously
1
BRANCH
checked out per worktree at a time

4Internal Working: What Happens When You Add a Worktree

Now let’s walk through exactly what happens internally, step by step, when a new worktree is created.
flowchart LR
    A["Developer requests a new worktree for a branch"] --> B["Git verifies the branch isn't already checked out elsewhere"]
    B --> C["A new working directory folder is created"]
    C --> D["Files for that branch are checked out into the new folder"]
    D --> E["A new, separate index is created for this worktree"]
    E --> F["The worktree is registered, linked back to the shared repository"]
    
FIG 4.1 — The internal steps Git follows when creating a new worktree

Step by step, in plain language: first, the developer specifies which branch they want checked out in a new worktree, and where the new folder should live. Second, Git checks an important safety rule, covered fully in Chapter 6: the same branch cannot be simultaneously checked out in more than one worktree at once, so Git verifies this branch isn’t already in use elsewhere. Third, Git creates the new folder on disk. Fourth, it checks out that branch’s files into this new folder, exactly as an ordinary branch switch would populate a working directory. Fifth, a new, independent staging area is set up specifically for this worktree, kept separate from any other worktree’s staging area. Finally, this new worktree is registered as linked to the same, shared underlying repository, meaning any commit made here becomes immediately part of the same shared history every other worktree can see and build on.

?
Why It Matters

Because every worktree shares the same object database, a commit made in one worktree is instantly visible from any other worktree connected to that same repository — there’s no separate syncing or fetching step needed between worktrees of the same repository, unlike with genuinely separate clones.

5Data Flow & Lifecycle: Using Several Worktrees in a Real Workflow

Following a realistic, multi-branch task from start to finish shows how worktrees fit into an actual working day.
1

Primary Work Continues Undisturbed

A developer is deep into a large feature branch, with several files modified but not yet committed, in their main working folder.

2

An Urgent Request Arrives

A critical bug needs an immediate fix on the main branch — but switching branches in the current folder would disturb the in-progress feature work.

3

A New Worktree Is Created

The developer creates a second worktree checked out to the main branch, in a completely separate folder, as detailed in Chapter 4.

4

The Fix Is Made and Committed

Working entirely within this second, separate folder, the developer fixes the bug and commits the change — a commit that immediately becomes part of the shared history.

5

The Fix Is Pushed

The fix is pushed to GitHub directly from this worktree, exactly as it would be from any ordinary, single-checkout repository.

6

The Feature Work Resumes Exactly Where It Was

The developer returns to their original folder, where the in-progress feature work sits completely untouched, exactly as it was left before the interruption.

Notice how the entire urgent-fix detour happened without a single stash, without a single branch switch in the original folder, and without any risk of losing or disturbing the original, uncommitted feature work.

6The Core Safety Rule: One Branch, One Worktree

Worktrees come with one especially important restriction, worth understanding clearly and precisely.

Git enforces a strict rule: the exact same branch cannot be checked out in more than one worktree at the same time. If you try to check out a branch that’s already checked out elsewhere, Git refuses and reports the conflict, rather than allowing it. This restriction exists for a genuinely important reason, not as an arbitrary limitation.

!
Warning

If the same branch could be checked out in two places at once, each worktree could independently move that branch’s pointer forward with new commits, creating an immediate, confusing conflict about which worktree’s version of the branch is actually correct. Preventing this scenario entirely, rather than trying to reconcile it after the fact, is exactly why Git enforces one-branch-per-worktree as a hard rule.

This restriction doesn’t meaningfully limit worktrees’ usefulness in practice, since the entire point is working on genuinely different branches simultaneously — needing the exact same branch open in two places at once is a rare, and generally confusing, situation to actually want in the first place.

7High-Level Concept: Worktrees vs. Stashing vs. Cloning

Three different Git capabilities can all address a “I need to work on something else temporarily” situation — understanding when each one genuinely fits best matters.
ApproachWhat It DoesBest Suited For
StashingTemporarily sets aside uncommitted changes, then restores them later, all within one working directoryA brief, single-folder interruption where switching branches in place is acceptable
WorktreesCreates a genuinely separate, simultaneous working folder for another branch, sharing the same repositoryWorking on, or comparing, two or more branches truly at the same time
Cloning AgainCreates an entirely independent copy of the whole repository, including its own full object databaseSituations needing genuine, complete independence — different remotes, or entirely separate configuration per copy

Worktrees occupy a genuinely useful middle ground: more capability and less disruption than stashing, but far more efficient and tightly connected than a completely separate clone. Choosing the right tool for a given situation comes down to exactly how much separation and independence the task actually requires.

8Advanced Topic: Worktrees for Parallel Testing & Builds

Beyond quick interruptions, worktrees enable a genuinely different category of workflow: running several branches’ code at the same time.

Some tasks — running a slow, thorough test suite, or building a large application — take real, meaningful time to complete. If you can only have one branch checked out at once, you’re forced to either wait for that process to finish before switching to other work, or interrupt it partway through. With worktrees, a slow test run or build can proceed undisturbed in one worktree’s folder, while genuinely new, separate development work continues simultaneously in another.

Comparing Performance Across Two Branches

A team wants to directly compare the performance of a proposed optimization against the current, unmodified code. Rather than repeatedly switching a single folder back and forth — which risks subtle inconsistencies from leftover build artifacts — they set up two separate worktrees, one for each branch, and run identical benchmark tests against each folder independently and simultaneously, producing a cleaner, more directly comparable result.

9Very Advanced Topic: Worktrees & Ignored, Untracked State

A subtle but important detail: some things genuinely don’t transfer automatically between worktrees, even though they share the same repository.

Because each worktree has its own genuinely separate working directory, as covered in Chapter 3, anything that exists only as an untracked or ignored file — build artifacts, locally installed dependencies, environment-specific configuration files not committed to the repository — does not automatically appear in a newly created worktree. Only content that’s actually part of Git’s tracked, committed history (or explicitly copied over manually) shows up in a fresh worktree’s folder.

i
Key Insight

This is a direct, logical consequence of what’s shared versus separate between worktrees, as covered in Chapter 3: the object database — genuinely committed content — is shared, but the working directory’s actual files on disk, including anything never committed, are not. A new worktree often needs its own fresh setup step — installing dependencies, generating local configuration — exactly as a brand-new clone would.

Teams that use worktrees heavily often build a small amount of tooling or a documented checklist around this reality, ensuring a newly created worktree gets whatever untracked setup it needs quickly and consistently, rather than each developer rediscovering this requirement independently every time.

10Very Advanced Topic: Removing & Cleaning Up Worktrees

Worktrees, once created, need to be deliberately cleaned up when no longer needed — simply deleting the folder isn’t quite the complete picture.

Because Git specifically registers and tracks each active worktree, as covered in Chapter 4, a worktree that’s no longer needed should generally be removed through Git’s own worktree-management commands rather than just manually deleting its folder from the file system. Using Git’s proper removal process cleanly un-registers the worktree and frees up its branch to be checked out elsewhere again, honoring the one-branch-per-worktree rule from Chapter 6.

If a worktree’s folder is deleted manually, outside of Git’s own awareness — say, by directly removing it in a file browser — Git can be left with a stale, “administrative” record of a worktree that no longer physically exists on disk. Git provides a dedicated cleanup step specifically to detect and clear out these leftover, stale references, keeping the repository’s worktree bookkeeping accurate and consistent.

!
Warning

Removing a worktree that still has uncommitted changes in it can permanently lose that work, exactly as deleting any working directory with unsaved changes would. Always ensure everything important has been committed and, ideally, pushed before removing a worktree you no longer need.

11Complex Concept: How Worktrees Relate to GitHub Specifically

Worktrees are entirely a local, client-side Git feature — worth understanding precisely where GitHub does and doesn’t enter this picture.

GitHub, as a hosting platform, has no direct concept of “worktrees” at all — worktrees exist entirely on your own computer, as a way of organizing how you locally interact with a repository’s history. When you push commits made from any worktree, GitHub receives and stores those commits exactly as it would from any ordinary, single-checkout local repository; from GitHub’s perspective, there’s no visible difference at all between a commit that came from a worktree and one that came from a conventional, single-folder checkout.

?
Why It Matters

This means worktrees are entirely a personal, local productivity tool — adopting or abandoning them has zero effect on how a project is structured on GitHub, what collaborators see, or how pull requests, branches, or history appear there. You can freely use worktrees for your own local workflow without needing any coordination or agreement from the rest of your team, since it changes nothing about the shared, remote repository itself.

This is worth emphasizing precisely because it distinguishes worktrees from many of the other concepts covered elsewhere in this guide series — release branches, pull requests, GitHub Actions — which do involve genuine, visible coordination on the shared, hosted repository. Worktrees, by contrast, are purely about how one individual developer chooses to organize their own local working environment.

12Advantages, Disadvantages & Trade-offs

Worktrees offer genuine, real benefits, but they aren’t automatically the right fit for every situation or every developer’s working style.
AspectAdvantageTrade-off / Cost
EfficiencyShares one object database instead of duplicating history across multiple clonesEach worktree still needs its own disk space for checked-out files and untracked setup
Uninterrupted workIn-progress, uncommitted changes in one worktree are never disturbed by working in anotherRequires remembering which folder corresponds to which branch and purpose
ParallelismEnables genuinely simultaneous builds, tests, or comparisons across branchesRunning multiple resource-intensive processes at once still consumes real system resources
Simplicity vs. cloningFar lighter-weight than maintaining several fully separate repository clonesUntracked, uncommitted setup doesn’t automatically carry over to a new worktree, as covered in Chapter 9
GitHub compatibilityFully transparent to GitHub — no special coordination or team buy-in requiredPurely a local convenience; doesn’t change or improve anything about the remote, shared repository itself

The core trade-off to internalize: worktrees trade a small amount of extra local organization and setup discipline — remembering which folder is which, and re-establishing untracked setup per worktree — for genuinely significant gains in avoiding disruptive branch switching and enabling real, simultaneous multi-branch work.

13Performance & Scalability Considerations

Worktrees have specific, worth-understanding effects on both disk usage and everyday Git operation speed.

Because the object database is shared rather than duplicated, as covered in Chapter 3, adding an additional worktree costs only the disk space needed for that branch’s actual checked-out files — not another full copy of the repository’s entire history. For a repository with a large, long history but modestly sized checked-out files, this makes worktrees dramatically more space-efficient than equivalent separate clones, especially as the number of simultaneous worktrees grows.

1
SHARED HISTORY
regardless of worktree count
N×
CHECKED-OUT FILES
disk cost per additional worktree
0
EXTRA FETCH/SYNC
needed between worktrees of the same repo

Ordinary Git operations that inspect or modify history — like viewing commit logs or fetching new updates — generally perform the same regardless of how many worktrees exist, since these operations work against the one, shared object database. Where care is still worth taking is with genuinely resource-intensive parallel tasks, like running several full builds or test suites across different worktrees truly simultaneously, since those consume real, independent system resources (processing power, memory) per worktree, even though the underlying Git data itself remains shared and efficient.

14Security Considerations

Worktrees, being a purely local feature, carry more modest security implications than some other topics in this guide series, but a few are genuinely worth knowing.
!
Warning

Because every worktree shares the exact same underlying repository and its history, any sensitive content already committed to that history — such as an accidentally committed credential, covered in a related guide — remains equally present and accessible from every single worktree, not isolated to just the original one. Worktrees provide no additional isolation or protection around already-committed, sensitive content.

It’s also worth remembering that untracked, worktree-specific files — such as locally generated credentials, configuration, or environment files, covered in Chapter 9 — need to be handled with the same care in every worktree individually as they would in a single, ordinary checkout; nothing about using worktrees changes the underlying best practices around keeping sensitive, untracked local files out of version control and appropriately protected.

Finally, since removing a worktree with uncommitted work can permanently lose that work, as covered in Chapter 10, treating worktree cleanup with the same care as any other operation capable of discarding uncommitted changes is a reasonable, sensible precaution, especially on a worktree that might contain sensitive, not-yet-backed-up experimental work.

15Design Patterns & Anti-Patterns

Developers who adopt worktrees regularly converge on a handful of recognizable habits — some genuinely productive, some that create needless confusion.

The Dedicated-Hotfix-Worktree Pattern keeps one worktree permanently set aside, checked out to the main or release branch, specifically ready for urgent fixes at a moment’s notice — directly mirroring the scenario walked through in Chapter 5.

The Comparison-Pair Pattern deliberately sets up two worktrees side by side specifically to compare behavior, performance, or output between two branches directly and simultaneously, as covered in Chapter 8.

DECISION — SHOULD EVERY BRANCH GET ITS OWN PERMANENT WORKTREE? Common Pitfall
The Situation

Excited by the flexibility worktrees offer, a developer starts creating a brand-new worktree for every single branch they ever touch, accumulating dozens of folders over time.

Why This Becomes a Problem

As covered in Chapters 9 and 13, each worktree needs its own untracked setup and consumes its own real disk space for checked-out files — a large, unmanaged pile of forgotten worktrees becomes genuinely difficult to navigate and wastes real, if modest, system resources.

The Better Pattern

Create worktrees deliberately, for genuinely simultaneous, active needs, and remove them promptly through Git’s own cleanup process, as covered in Chapter 10, once that specific need has passed.

Common anti-patterns to avoid: the Worktree Hoarding pattern described above; the Manual Folder Deletion anti-pattern (deleting a worktree’s folder directly instead of using Git’s proper removal process, leaving stale, confusing administrative records behind, as covered in Chapter 10); and the Assumed-Isolation misunderstanding (believing a worktree provides some kind of security or content isolation from the rest of the repository’s shared history, when in fact, as covered in Chapter 14, it provides none).

16Best Practices & Common Mistakes

A handful of simple, grounded habits help developers get genuine, lasting value from worktrees without running into avoidable confusion.
1

Name Worktree Folders Clearly

Use folder names that make each worktree’s purpose or branch immediately obvious, avoiding confusion about which folder is which.

2

Create Worktrees Deliberately, Not by Default

Reach for a worktree when you genuinely need simultaneous, separate access to another branch, rather than habitually for every task.

3

Remember Untracked Setup Doesn’t Transfer

Plan for re-running local, untracked setup steps in a new worktree, as covered in Chapter 9, rather than assuming everything carries over automatically.

4

Clean Up With Git’s Own Commands

Remove worktrees you no longer need through Git’s proper process, not by manually deleting the folder, to keep repository bookkeeping accurate.

5

Commit or Push Before Removing a Worktree

Always confirm important work is safely committed and, ideally, pushed before removing any worktree, to avoid permanently losing uncommitted changes.

Common mistakes beginners make: trying to check out the same branch in two worktrees at once and being confused by Git’s refusal, without understanding the reasoning covered in Chapter 6; assuming a fresh worktree automatically includes locally installed dependencies or configuration; and manually deleting a worktree’s folder instead of using Git’s dedicated removal process, leaving behind confusing, stale administrative records.

17Real-World & Industry Examples

Seeing worktrees used in realistic, industry-style scenarios makes their practical value concrete.

On-Call Engineering Response

An engineer on on-call duty, deep in unrelated, in-progress work when an urgent production issue arises, keeps a dedicated worktree checked out to the main branch specifically ready for exactly this situation, allowing an immediate, undisturbed response without any disruption to their other, ongoing work.

Long-Running Automated Test Suites

A developer whose project has an unusually slow, thorough test suite uses a separate worktree specifically to run that full suite in the background, continuing genuinely separate, active development work in their primary worktree while the tests complete undisturbed.

Reviewing a Colleague’s Pull Request Locally

A developer wanting to check out and run a colleague’s proposed changes locally, without disturbing their own in-progress feature branch, creates a temporary worktree specifically for reviewing that pull request, removing it cleanly once the review is complete.

Documentation Writers Working Across Versions

A technical writer maintaining documentation for both a current and a previous supported version of a product keeps two separate worktrees open simultaneously, one per version’s branch, letting them cross-reference and copy relevant content between the two without constantly switching a single folder back and forth.

18Frequently Asked Questions

Q1Does creating a worktree duplicate the entire repository?
No. As covered in Chapter 3, worktrees share one single, common object database — only the checked-out files and staging area are separate per worktree, making them far more efficient than a full, separate clone.
Q2Can two worktrees have the same branch checked out at once?
No. As covered in Chapter 6, Git strictly enforces one branch per worktree at a time, specifically to prevent confusing, conflicting updates to the same branch from two different places simultaneously.
Q3Does GitHub know or care whether I use worktrees locally?
No. As covered in Chapter 11, worktrees are entirely a local, client-side feature — GitHub sees ordinary commits and branches, with no visible difference based on whether they came from a worktree.
Q4Do installed dependencies automatically appear in a new worktree?
No. As covered in Chapter 9, only tracked, committed content is shared through the repository — untracked files like installed dependencies or local configuration need to be set up separately in each worktree.
Q5Is it safe to just delete a worktree’s folder when I’m done with it?
Not ideally. As covered in Chapter 10, Git’s own removal process properly un-registers the worktree; manually deleting the folder can leave behind stale, confusing administrative records that need separate cleanup.
Q6Do worktrees provide any extra security isolation between branches?
No. As covered in Chapter 14, every worktree shares the exact same underlying repository and history — any sensitive content already committed remains equally accessible from any worktree connected to that repository.

19Summary and Key Takeaways

What to Remember

  • A worktree is a genuinely separate, simultaneous working folder for a branch, linked back to one shared, common Git repository rather than duplicating it.
  • It exists to solve the friction of constantly switching branches — enabling multiple branches to be worked on, tested, or compared truly at the same time, without disruption.
  • The object database and branch references are shared across worktrees, while each worktree keeps its own separate, independent working directory and staging area.
  • Git strictly enforces one branch per worktree at a time, specifically to prevent conflicting, simultaneous updates to the same branch from different places.
  • Untracked, uncommitted files — like locally installed dependencies — don’t automatically carry over into a new worktree, since only genuinely committed content is shared.
  • Worktrees are entirely a local, client-side feature — GitHub itself has no visibility into or special handling for them, so adopting worktrees requires no team-wide coordination.
  • Worktrees should be created deliberately and removed properly, using Git’s own management commands, to avoid disk clutter, confusion, or accidentally losing uncommitted work.