Git worktrees: Parallel development without the context-switching pain

Git worktrees have been part of Git since 2015, but they've recently gained mainstream attention. The core idea is simple: instead of juggling branches within a single working directory, you can check out multiple branches into separate folders simultaneously. This eliminates the need to stash changes, switch branches, and restore your environment every time you need to context-switch.

The old way: Stash, switch, and restore

Without worktrees, handling an urgent bug while mid-feature means a disruptive sequence of Git commands. You stash your work, switch to your main branch, pull updates, create a bugfix branch, fix, commit, and push. After merging a pull request, you return to your main branch, pull again, delete the bugfix branch, and finally pop your stash to resume your original work.

The mental overhead is significant. Every switch means reloading files, reinstalling dependencies like node_modules, and reorienting yourself. Some developers work around this with complex git stash manipulations or by keeping multiple clones of the same repository.

The worktree flow: Zero disruption

Worktrees change this entirely. A single command creates a sibling folder, bases it on your main branch, and checks out a new branch in that folder. Your original workspace—editor state, open files, running processes—remains completely untouched. To handle the bug, you simply open that new folder in another editor window or cd into it.

After the bugfix branch is merged, you delete the temporary folder and carry on. No stash conflicts, no interrupted sessions, no reinstallation of dependencies in your primary workspace. Worktrees let you truly work in parallel, and modern tools have embraced them accordingly—VS Code ships with full worktree support built in.

Why now?

Worktrees remained largely unknown for years. Many Git GUIs treated them as second-class citizens or omitted them entirely, and most developers stuck with the familiar pattern: feature branch, work, pull request, merge, repeat.

The shift in software development practices changed that. AI-driven development means more parallel sessions than ever before, with agents and humans working side by side on the same repository. The GitHub Copilot app relies on worktrees as its default session mode, and many other modern tools follow suit.

Caveats and considerations

Worktrees solve many problems, but there are genuine trade-offs:

  • Dependency bloat: Each worktree folder needs its own copy of project dependencies. Running npm install or pip install across multiple worktrees can quickly fill your disk.
  • Folder management: You must remember to delete worktree folders after merging to keep your parent directory tidy. Some apps handle this automatically; in the terminal, you do it yourself.
  • Global .gitignore patterns: Worktrees created inside your main repo directory need to be added to .gitignore to prevent accidental tracking. Creating them outside the main directory—which many apps do by default—avoids this issue.
  • One-worktree-per-branch: Git prevents checking out the same branch in two different worktrees at once to protect against data corruption.

Getting started with worktrees in the GitHub Copilot app

Worktrees require no configuration there. On the app's home screen, a dropdown lets you choose where to run a new session; a new worktree is the default option. Once a session is running, clicking its name reveals the generated worktree name, the path where it's located, the project it belongs to, and a summary of current changes.

Are worktrees right for you?

Like most workflow decisions, the answer depends on how you work. If you rarely need parallel streams of work, the traditional branch-and-stash model may serve you fine. If you frequently bounce between tasks—or run multiple agents alongside human reviews—worktrees offer a significantly smoother experience. There is no rule against mixing both approaches.