Git Worktrees: The Secret Weapon for Seamless Context Switching in Development

Every developer has been there: deep in the zone, solving a complex problem or crafting elegant code, when suddenly—notification. It's the dreaded "PRODUCTION IS DOWN" alert or a request from your product manager to "INVESTIGATE THIS COOL IDEA!" You're pulled out of your flow, forced to context switch, and face the familiar ritual of stashing your work.

You open the message, analyze the situation, and decide running locally might help. You return to your editor only to realize you have modified files, uncommitted changes, and a messy staging area. The typical workflow involves a deep breath, a sigh of frustration, and a series of Git commands:

git stash save
# Forget you had unstaged files...
git stash apply
git add .
git stash save
git checkout main
git pull
# Clean workspace, rebuild, run locally

After successfully resolving the production issue and returning to your desk, you remember: you made changes in a dependency package but can't recall which file it was. The frustration mounts as you realize you'll need to track it down all over again.

Enter Git worktrees—a powerful feature that allows you to switch contexts without having to "close down" your current work state.

Understanding Git Worktrees

Introduced in Git 2.5.6, a worktree is a self-contained directory within your Git repository that points to a specific branch. This enables you to have a dedicated directory for each branch you're working on, with the only limitation being that a branch can only be referenced once across all worktrees.

At its simplest, a worktree copies the contents of a branch into a separate directory. When you run git clone git@my-org:my-repo.git, you're actually creating a worktree for the default branch (usually main or master).

Setting Up for Worktrees

For optimal worktree usage, it's best to start with a bare clone of your repository. A bare clone contains all the repository's metadata but no working files—no .git directory in your project folder because the clone itself is the Git repository.

git clone --bare git@my-org:my-repo.git my-repo
cd my-repo

This setup prevents potential issues with committing changes within your project and provides a cleaner foundation for managing multiple worktrees.

Creating Your First Worktree

Let's create a worktree for the main branch:

git worktree add main

This command creates a main directory in your current location and checks out the main branch into it. Running ls -l will show the new directory, and cd main will reveal your codebase ready for modifications.

Handling Production Emergencies with Worktrees

Now, let's revisit our production emergency scenario. Imagine you're working on a feature branch called "Add-cat-gifs" with several changes across multiple files. Instead of stashing everything, you can create a new worktree for your hotfix:

cd ../main
git pull
git worktree ../hotfix -b hotfix-branch

This sequence pulls the latest changes from main and creates a new worktree in the hotfix directory. You can then cd ../hotfix and find yourself with a clean working environment—no previous changes, no staged files, just a fresh branch ready for your emergency fix.

Important Considerations

When creating worktrees, pay attention to:

  1. Path specification: Use ../ to reference directories outside your current worktree location
  2. Branch creation: New worktrees branch from your current location. If you run git worktree add ../hotfix -b hotfix-branch while on branch-a with uncommitted changes, those changes will come with you to the new branch
  3. Base commit: To create a branch from a specific commit, use: git worktree add my-worktree -b my-new-branch <commit-hash>

The Developer Workflow with Worktrees

With worktrees, your workflow becomes much more fluid:

  1. Create dedicated worktrees for each context (feature, hotfix, investigation)
  2. Make changes in the appropriate worktree
  3. When done, commit and push changes from the relevant worktree
  4. Seamlessly switch back to your original feature worktree without losing progress

Remember that each worktree requires its own local build setup and environment configuration:

# In each new worktree
npm install  # or yarn, pip, etc.
cp .env.example .env
# Configure your environment variables

Benefits Beyond Context Switching

Worktrees offer several advantages beyond just maintaining context:

  • Clean histories: Each worktree provides a clean slate, reducing merge conflicts
  • Parallel development: Work on multiple features simultaneously without interference
  • Experimentation safely: Try experimental changes in isolated environments
  • Team collaboration: Easily share specific branch contexts with team members

Best Practices and Limitations

While worktrees are powerful, keep these best practices in mind:

  • Start with a bare repository: As mentioned, this prevents committing changes within your project
  • Clean up regularly: Remove unused worktrees with git worktree prune
  • Be mindful of disk space: Each worktree contains a full copy of the repository files
  • Remember branch uniqueness: A branch can only be checked out once across all worktrees

Conclusion

Git worktrees transform how developers handle context switching, eliminating the friction of stashing and unstashing while maintaining clean, isolated working environments. By leveraging this feature, you can preserve your development flow, reduce cognitive load, and increase productivity—especially when juggling multiple tasks or responding to urgent issues.

The next time you're faced with the dreaded context switch, remember that Git worktrees provide a more elegant solution than the traditional stash-and-hope approach. Your future self—and your productivity—will thank you.

Source: Originally published at https://futurepixels.co.uk/posts/improving-my-productivity-and-context-switching-with-git-worktrees/