Git worktrees tutorial: several branches at once
Work on several branches at the same time, each in its own folder, without stashing and without cloning twice. This tutorial starts with plain Git on the command line, so you understand what is happening on disk, then does the same work in Mergepond.
What a worktree is
A Git repository has one object store (the .git folder) and, normally, one working folder with one branch checked out. A worktree is a second working folder attached to the same repository. It has its own checked-out branch, its own index and its own files, but it shares the commits, branches and tags with the main folder.
That sharing is the point. Creating a worktree takes a second or two and costs almost no disk, because nothing is copied except the files of the branch you check out. A commit you make in one worktree shows up immediately in the history of every other, because they all read the same .git.
Compare the two things people reach for instead:
git stashputs your half-done change aside so you can switch branches in the same folder. It works, until you have three stashes and cannot remember which is which, or a stash fails to apply because the branch moved.- A second clone gives you a second folder, but it is a separate repository. Its branches are not your branches until you push and fetch, it doubles the disk, and
node_modulesand the rest have to be installed again from nothing.
A worktree is a second folder that is still the same repository. The blog post Git worktrees vs stash vs a second clone goes deeper on when each one wins.
Create your first worktree with Git
Start in your repository's main folder. Pick a layout for the worktree folders that keeps them together and out of the repository itself; a sibling folder named after the repository works well.
cd ~/src/api
git worktree add ../api.worktrees/fix-flaky-tests -b fix/flaky-testsThat creates the folder ~/src/api.worktrees/fix-flaky-tests, creates the branch fix/flaky-tests from your current commit, and checks it out there. Open the folder in your editor and work as usual. Back in ~/src/api, nothing has changed.
To check out a branch that already exists, leave off -b:
git worktree add ../api.worktrees/release-2.3 release/2.3For a branch that exists only on the remote, fetch first and Git will set the local branch to track it:
git fetch origin
git worktree add ../api.worktrees/search origin/feat/searchAnd for a pull request on GitHub, fetch the pull request's head into a local branch, then add a worktree for it:
git fetch origin pull/123/head:pr-123
git worktree add ../api.worktrees/pr-123 pr-123List, move and remove worktrees
git worktree listprints every folder, the commit it is at and its branch, with the main folder first. Move a worktree with git worktree move <old> <new> and remove one with git worktree remove <path>; remove refuses if the folder has uncommitted changes unless you add --force.
Removing a worktree deletes the folder. It does not delete the branch. If you are finished with the branch too, delete it separately:
git worktree remove ../api.worktrees/fix-flaky-tests
git branch -d fix/flaky-testsIf you delete a worktree folder in Finder instead, Git still remembers it. git worktree prune forgets folders that no longer exist. And if a worktree lives on a drive that is not always mounted, git worktree lock <path> stops prune from forgetting it while the drive is away.
One rule to remember: a branch can be checked out in only one worktree at a time. git worktree add ../x main while main is checked out in the main folder fails with fatal: 'main' is already checked out at '~/src/api'. Create a new branch instead, or switch the other folder to something else first.
Worktrees and your tools
Editors and language servers see each worktree as a separate project folder; open the folder, not the repository. Package managers install per folder unless you point them at a shared store, which is why a worktree without node_modules is the first thing people notice.
Repository config in .git/config and hooks in .git/hooks are shared by every worktree. If you need a setting in one worktree only, git config --worktree writes it to that worktree's own config instead.
Do the same in Mergepond
Everything above is one sheet and one view in Mergepond.
- Open your repository and press ⌘N, or choose File › New Worktree…. The sheet opens on "New branch", with "Starts from" set to your current branch.
- Type a branch name. The Folder field fills in from your folder pattern, which by default is
../<repo>.worktrees/<branch>, sofix/flaky-testslands at../api.worktrees/fix-flaky-tests, the same layout as the commands above. - To check out a branch that exists, pick "Existing branch" and type its name, or
origin/feat/searchfor a remote branch. For a pull request, pick "Pull request" and type the number; Mergepond fetches it from origin into the branchpr-123. - Leave "Run the setup recipe" ticked if you have one (see Worktrees that set themselves up), then click "Create worktree".
- The sheet shows "Setting up" while the recipe runs, then "Worktree ready" with an "Open in a new window" button. You can close the sheet early; setup carries on and the board shows its progress.
Press ⌘3 for the Worktrees view. Each worktree is a card with its branch, how many files have changed, how many commits it is ahead or behind its upstream, its last commit, and when there is nothing left to do, "Safe to remove" with the folder size. The cards sit in three columns: Working, Ready for review (committed and not yet pushed, or pushed and waiting), and Merged or gone.
The board is part of Pro from Mergepond 1.0.7. On Free, the same tab is a plain list of every worktree with its branch, folder and an "Open" button, and you create, open and remove worktrees the same way.
The sidebar lists worktrees under the repository too. Click one to open it in this window, or ⌘-click to open it in a new window; on the board, "Open" opens a new window and "Open here" uses this one. Right-click for Open in Terminal, Reveal in Finder and Remove worktree….
Remove and clean up
Right-click a card, or use its More button, and choose "Remove worktree…"; cards in the Merged or gone column have a "Remove worktree" button in plain sight. If the worktree has uncommitted changes, Mergepond says so and offers "Commit first" alongside "Remove and lose changes". If it has commits that are not on the remote, it offers "Push, then remove". When it is safe, the dialog says what the Git command does: it deletes the folder, and the branch and its commits stay.
With Pro, "Clean up" in the board's header, or "Remove N merged or gone worktrees…" in the palette, gathers everything in the Merged or gone column into one sheet, shows how much disk it frees, and removes them together. Worktrees with uncommitted changes start unticked.
Troubleshooting
fatal: '<branch>' is already checked out at …: the branch is in another worktree. Switch that worktree to a different branch, or use a new branch.- You deleted a worktree folder by hand: Mergepond shows it as "Folder is missing" and Clean up removes the record, which is what
git worktree prunedoes. - Submodules in a worktree start empty; use "Update submodules" from the palette or the sidebar. Git LFS files download with "Pull LFS files" once LFS is installed.
Get more from it
- Name branches with a prefix per kind of work (
fix/,feat/,agent/) and the worktree folders sort themselves, because the pattern turns slashes into dashes. - Put your
.envandnode_modulesinto a setup recipe once, and every worktree after that is ready to run. See Worktrees that set themselves up. - Give each coding agent a worktree of its own and the board becomes a status page for them. See Run coding agents in parallel.
- Let the agent do the
git worktree additself. Mergepond comes withpond, a command line tool and MCP server that makes a worktree, runs the recipe and marks the card;pond new fix/flaky-testsfrom a terminal does the same as the sheet. See Let your coding agent make its own worktrees. - With Pro, the same sheet works on a repository you opened over SSH; the worktrees are created on that machine.