Using worktrees with IDEs and language servers Jump to heading

Worktrees give you several checkouts of one repository, each on its own branch, sharing one object store. Git handles that cleanly; the tools around Git sometimes do not. Editors open the wrong folder, language servers index every worktree at once, build tools write caches that one worktree reads from another, and a few tools expect .git to be a directory and break when it is a file pointing elsewhere. None of this is a reason to avoid worktrees, but each needs a small adjustment. This page covers opening worktrees in editors, keeping dependencies and caches separate, controlling indexing cost, and fixing tools that misread a worktree, within Git worktrees for parallel development.

When to use this approach Jump to heading

  • You use worktrees and your editor or language server misbehaves in them.
  • Opening a second worktree makes your machine slow while it indexes.
  • Builds in one worktree pick up artefacts or caches from another.
  • You are choosing between worktrees and clones, as in worktrees vs multiple clones.

Step 1 — Lay worktrees out next to each other Jump to heading

Put worktrees side by side in a parent directory rather than inside the main checkout. Nested worktrees get picked up by editors, file watchers, test runners and search tools scanning the main checkout.

# Avoid: ~/src/app/.worktrees/feature-x  (inside the main tree)
git -C ~/src/app worktree add ../app-feature-x -b feature/x
git -C ~/src/app worktree list
# /home/me/src/app            1a2b3c4 [main]
# /home/me/src/app-feature-x  1a2b3c4 [feature/x]
Where should a new worktree go?Next to the main checkout is the safest layout, because no tool scanning one tree will see another. Inside the main checkout is risky, since editors, watchers and test runners may descend into it. Under a bare repository directory is a deliberate layout where every working tree is a sibling.Where would you put it?next to main checkoutRecommendedisolated from scannersinside main checkoutAvoidtools descend into itunder a bare repo dirDeliberate layoutall trees are siblingsif you must nest, add the directory to .git/info/exclude and editor ignores

Step 2 — Open each worktree as its own project Jump to heading

Open each worktree as a separate editor window or project. Most editors key their settings, run configurations and language-server sessions by folder, so each worktree gets its own state.

code ~/src/app-feature-x           # VS Code: a new window per worktree
idea ~/src/app-feature-x           # JetBrains: open as a separate project

Editors with built-in Git support recognise worktrees and show the right branch. If yours shows the main checkout’s branch, it is reading the wrong .git; update it, since current versions handle worktrees.

Step 3 — Keep dependencies and build output per worktree Jump to heading

Dependencies and build output live in the working tree — node_modules, target, .venv, build — so each worktree has its own, which is what you want: different branches may need different dependency versions. Install them when you create the worktree.

git -C ~/src/app worktree add ../app-feature-x -b feature/x
cd ~/src/app-feature-x
npm ci                      # or: python -m venv .venv && .venv/bin/pip install -r requirements.txt

Shared caches outside the tree — the npm cache, Gradle’s cache, pip’s cache — are safe to share and make each install fast.

Step 4 — Avoid caches that leak between worktrees Jump to heading

Some tools keep caches keyed by repository rather than by working tree, or in a location derived from .git. Then one worktree’s cache is used by another, with confusing results. Point such caches into the working tree.

# Example: a tool that caches under the git directory
git rev-parse --git-dir          # /home/me/src/app/.git/worktrees/app-feature-x
git rev-parse --git-common-dir   # /home/me/src/app/.git   (shared by all worktrees)
# Configure the tool to cache under the working tree instead
export TOOL_CACHE_DIR="$PWD/.cache/tool"

Tools that use --git-common-dir for caches share them across worktrees; those using --git-dir keep them separate.

What each worktree has and what it sharesEach worktree has its own working files, index, HEAD, dependencies and build output. All worktrees share the object database, refs, configuration and hooks in the common Git directory. Tools that store state in the common directory share it across worktrees.Per worktreeworking filesindex, HEADnode_modules, build/editor stateSharedobjectsbranches, tagsconfig (by default)hooksa tool caching in the shared column is shared across every worktree

Step 5 — Control language-server and indexing cost Jump to heading

Each open worktree is indexed separately. Close windows for worktrees you are not using, and exclude heavy directories from indexing in each.

// .vscode/settings.json (committed, applies in every worktree)
{
  "files.watcherExclude": { "**/node_modules/**": true, "**/build/**": true, "**/.cache/**": true },
  "search.exclude": { "**/node_modules": true, "**/build": true }
}

Step 6 — Fix tools that expect .git to be a directory Jump to heading

In a linked worktree, .git is a file containing gitdir: /path/to/main/.git/worktrees/name. Older tools that open .git/HEAD or .git/config directly fail. Use Git commands to find paths instead of hard-coding them.

cat .git                                   # gitdir: /home/me/src/app/.git/worktrees/app-feature-x
git rev-parse --git-path HEAD              # correct HEAD file for this worktree
git rev-parse --git-path hooks             # hooks location (shared)
git rev-parse --show-toplevel              # root of this working tree

If a third-party tool cannot be fixed, report it to the tool’s maintainers and use a separate clone for it in the meantime.

Step 7 — Clean up editor state with the worktree Jump to heading

When you remove a worktree, close its editor window first so the editor does not recreate files, then remove the worktree with Git rather than deleting the directory.

git -C ~/src/app worktree remove ../app-feature-x
git -C ~/src/app worktree prune

Removing stale worktrees safely is covered in cleaning up stale worktrees safely.

A worktree's lifecycle with an editorCreate the worktree next to the main checkout, install its dependencies, and open it as a separate editor project. Work and commit there. When done, close the editor window, then remove the worktree with git and prune stale entries.worktree addsibling directoryInstall depsper worktreeOpen projectown windowClose windowbefore removalworktree removethen prunedeleting the directory by hand leaves Git's bookkeeping behind

Validation checklist Jump to heading

Frequently Asked Questions Jump to heading

Can one editor window show several worktrees? Jump to heading

Multi-root workspaces can, but language servers may then treat them as one project and mix symbols. Separate windows are more predictable.

Do hooks run in every worktree? Jump to heading

Yes. Hooks live in the common Git directory and are shared, unless configured per worktree, as in per-worktree config and shared hooks.

Why does my editor show the wrong branch? Jump to heading

It is reading the main checkout’s .git directory instead of following the .git file in the worktree. Update the editor or its Git extension; current versions support worktrees.