A git worktree is an additional working directory of the same repository: a second folder with its own files, its own checked-out branch and its own staging area, which shares the history, the branches and the configuration with the original folder. With it you can have main open in one folder and feature/login in another at the same time, without cloning the repository twice and without running stash every time you switch tasks. The command has existed since git 2.5 (2015), but it's easy to overlook because it only makes sense once you know how a repository is built inside: what is shared between folders and what isn't.
TL;DR
- A git worktree is another working folder of the same repository: it has its own
HEAD, index and files, but shares the commits, branches, configuration and hooks with the main worktree.- A linked git worktree has no
.gitfolder, only a one-line.gitfile pointing to.git/worktrees/<name>, where git keeps what belongs to that worktree alone. That's why creating one is fast and doesn't duplicate the history.- A git worktree has two limits worth knowing: a branch can be checked out in only one worktree at a time, and it doesn't copy what git doesn't track (
node_modules,.env, builds).
What is a git worktree
A git worktree is an additional working directory of the same repository, with its own checked-out branch, its own HEAD and its own index; the commits, branches and configuration are shared with the main worktree.
The problem it solves is concrete. A freshly cloned repository has a single working folder, and only one branch can be checked out in it at a time. If you're halfway through feature/payments and someone asks you to look at a bug on main, you have three options, and none is comfortable: make a temporary commit, put your changes away with git stash, or clone the repository again into another folder. The first two force you to interrupt what you were doing; the third duplicates the whole history and creates a separate repository that can't see your local branches.
git worktree adds a fourth option: a second working folder in the same repository. In that folder you open main, fix the bug and commit, while feature/payments stays untouched in the original folder, half-finished changes included. Both folders read from and write to the same git database, so the commit you made in one shows up in the other immediately.
To understand why that works, and what exactly is shared, you need to separate the parts of a repository.
The three parts of a git repository
A git repository has three parts: the object database (the history), the references (the branches and tags that point into that history) and the working state (the checked-out branch, the index and the files in the folder).
| Part | What it holds | Where it lives |
|---|---|---|
| The object database | Every commit, tree and file content in the history | .git/objects |
| The references | The names that point to commits: branches (refs/heads/main), tags, remote branches |
.git/refs and .git/packed-refs
|
| The working state | Which branch is checked out (HEAD), what you staged for the next commit (the index) and the files you see in the folder |
.git/HEAD, .git/index and the working directory |
The first two parts are the repository itself: the history and the names that point into it. The third is your position within that history: which branch you're on, which files are checked out and which changes you've staged. A normal repository has one copy of each part, which is why you can only be in one place at a time.
A worktree duplicates only the third part. Each worktree has its own HEAD, its own index and its own folder of files, but they all share the object database and the references.
Git distinguishes two kinds of worktree. The folder where you cloned or initialized the repository, the one holding the real .git folder, is the main worktree. The ones you add with git worktree add are linked worktrees. Day to day they behave the same; the difference is that the main worktree can't be removed or moved with git worktree, because that's where the repository lives.
Keep reading
That is the first half. The full walkthrough — with the rest of the implementation, the trade-offs and the things that only show up in production — is on my blog:
Read the full post on ramonchancay.me →
Originally published at www.ramonchancay.me/blog/what-is-a-git-worktree.

Top comments (0)