Stop Stashing: A Better Git Workflow with Worktrees

You are deep into a new feature. Your editor has a dozen files open. Your local server is running. Then the alert comes in. There is a critical bug on production and you need to fix it immediately.

What do you do? The standard answer is git stash. You save your messy work in progress switch to the main branch pull the latest code create a hotfix branch fix the bug and push it. Then you switch back to your feature branch and run git stash pop hoping everything comes back cleanly. Often it does not. You might get merge conflicts or forget what was in the stash.

The stash is a temporary holding area. It feels like stuffing things in a closet before a guest arrives. It works but it is not a clean way to manage your work. There is a better tool for this exact problem. It is called git worktree.

The Friction of Stashing

The git stash is a stack. You push changes onto it and you pop them off. This is simple but it has weaknesses. Stashes are unnamed so it is hard to remember what stash@{2} contains. Popping a stash can cause conflicts with new changes you pulled on your feature branch. It is easy to end up with a list of old stashes you are too afraid to delete.

Stashing forces a context switch on your entire working directory. Your file system state changes. Your editor might get confused. Your running processes might need to be restarted. It is disruptive because it treats your project directory as a place that can only represent one branch at a time. But that is not how work actually happens.

Work is often parallel. You have a long term feature and a short term fix. git worktree understands this.

A New Directory for Each Task

A worktree is a linked working directory. You can have your main project directory on your feature branch and create a second directory next to it that is on the main branch. They share the same underlying .git repository data but they have separate checked out files.

This means no stashing. No context switching in your primary directory. You just cd into the other directory to work on the other task.

Let us walk through the hotfix scenario. You are in your project directory my-app working on the new-feature branch.

# You are in ~/projects/my-app
# You are on the new-feature branch

You get the alert about the bug. Instead of stashing you create a worktree. The command takes a path for the new directory and the branch you want to check out there.

# Create a new directory ../my-app-hotfix from the main branch
git worktree add ../my-app-hotfix main

Git will create a new directory for you at ~/projects/my-app-hotfix. It will be a clean working copy of the main branch. Now you can just change directories.

cd ../my-app-hotfix

Inside this new directory you are on the main branch. You can create your hotfix branch as usual.

git checkout -b fix/production-bug

# ... fix the bug ...

git commit -am “Fix critical production bug”
git push origin fix/production-bug

You can open a pull request and get it merged. All the while your original my-app directory is completely untouched. It is still on the new-feature branch with all your changes and running processes intact.

When you are done with the hotfix you can return to your feature work.

cd ../my-app
# Continue your work

There is nothing to pop or resolve. Your context was preserved.

Managing Worktrees

Worktrees are easy to manage. To see all your current worktrees you can run git worktree list. It will show you the path and current branch for each one.

When your hotfix branch is merged and you no longer need the separate directory you can clean it up. A worktree consists of two things. The directory with the files and a record inside the .git directory that links it.

First you remove the directory itself.

# Make sure you are not inside the directory you want to remove
cd ../
rm -rf my-app-hotfix

Now you need to tell Git to clean up its internal references. This command removes stale tracking data for worktrees that no longer exist on disk.

# Go back into your main project directory
cd my-app
git worktree prune

And that is it. Your project is back to a single working directory.

More Than Just Hotfixes

This pattern is useful for more than just emergencies. It makes any kind of parallel work simpler.

Use a worktree whenever you want to run a command or test something on a different branch without disrupting your current work.

Think about code reviews. A teammate asks you to review a pull request. Instead of stashing and checking out their branch you can create a worktree for it.

# Check out their branch into a new temporary directory
git worktree add ../pr-review-123 pr/123

Now you can cd ../pr-review-123 run the code test the changes and leave comments. Your own feature branch is safe. When you are done you remove the directory and prune the worktree.

Or maybe you need to run a long test suite before merging. You can check out your branch in a worktree kick off the tests and continue coding in your main directory.

The core idea is that context switching should be cheap. git worktree makes it as cheap as changing a directory. You stop thinking about saving your work and start thinking about creating new spaces to do work. It is a small change in tooling that leads to a much smoother workflow.

Consider the last time you had to juggle tasks.

— Rishi Banerjee
September 2025