What is a Git working tree?

Kenny DuMez
Kenny DuMez
Graphite software engineer


Note

This guide explains this concept in vanilla Git. For Graphite documentation, see our CLI docs.


The Git working tree, represents the current snapshot of your project, containing all the files and directories that are currently being tracked by Git, as well as any modifications, new files, or untracked resources. This guide will explain the Git working tree, including how to use the git worktree command for handling multiple working directories from the same repository.

The Git working tree is where you perform edits and modifications to your files. It sits alongside the Git directory, which stores the repository's metadata and object database. Changes made in the working tree can be staged to the index (also known as the staging area) and then committed to your repository's history.

When you clone a repository, Git creates a working tree that contains the latest version of every file from the repository. As you make changes, these modifications are only in your working tree until you decide to commit them.

The tree command, provides a hierarchical view of your project's directory structure. While not a Git command, it's useful for illustrating the concept of the working tree.

If tree is not installed on your system, you might need to install it first.

To install the command on linux run:

Terminal
sudo apt-get install tree

To install the tree command on macOS using homebrew run:

Terminal
brew install tree

After cloning a repository, running tree in the terminal will show you something like this:

Terminal
.
├── .git
│ ├── HEAD
│ ├── config
│ ├── objects
│ └── refs
├── .gitignore
├── README.md
└── src
├── index.js
└── style.css
3 directories, 5 files

This output displays the working tree of a simple project, with the .git directory containing Git's metadata and the rest of the files and directories making up the current state of your project.

The git worktree command allows you to have multiple working trees attached to the same repository, creating different directories per tree, enabling you to have multiple branches checked out simultaneously without having to switch back and forth.

Worktrees are automatically configured by Git when you add them. Each worktree has its own .git directory with a link back to the main repository's object database, ensuring that all worktrees stay in sync with the repository's state.

To add a new worktree, use git worktree add <path> <branch>:

Terminal
git worktree add ../feature-branch feature-branch

This command creates a new working directory at ../feature-branch and checks out the feature-branch branch there. Now you can work on feature-branch in this new directory while keeping your main working tree on another branch.

  • Add a new worktree: git worktree add <path-to-new-worktree> <branch>
  • List all worktrees: git worktree list
  • Remove a worktree: git worktree remove <path-to-worktree>
  • Prune worktrees: git worktree prune (Removes references to worktrees that are no longer valid.)

Multiple worktrees are particularly useful in scenarios where you need to:

  • Quickly switch between branches for testing or comparison without stashing or committing work in progress.
  • Isolate work on a new feature while keeping the main branch clean and deployable.
  • Handle hotfixes or urgent changes on a production branch while continuing development on a feature branch.

You are working on a new feature in a branch called feature-new-ui, and you need to quickly switch to your main branch to verify how something was implemented there, without losing your current progress and without having to commit work-in-progress changes.

Without worktrees: You would typically use git stash to save your changes temporarily, switch branches, and then switch back and apply your stash. This can be cumbersome and disrupt your workflow.

With worktrees:

  1. Create a new worktree for the main branch:
Terminal
git worktree add ../main-branch main
  1. Switch to the new worktree and verify the implementation:
Terminal
cd ../main-branch
# Do your verification here
  1. Return to your original feature work:
Terminal
cd ../original-repo-feature-new-ui

You want to start work on a new feature called feature-advanced-search, but it's crucial to keep the main branch in a clean and deployable state at all times.

Without worktrees: You would create a new branch and carefully manage your commits and merges to ensure main remains deployable.

With worktrees:

  1. Create a new worktree for the new feature branch:
Terminal
git worktree add ../feature-advanced-search feature-advanced-search
  1. Work on the feature in isolation:
Terminal
cd ../feature-advanced-search
# Develop your feature here without affecting the main branch

A critical bug is reported in the production version of your project, which requires an immediate hotfix on the production branch. Meanwhile, you are in the midst of working on a complex new feature on a separate branch.

Without worktrees: You would need to carefully stash your changes, switch to the production branch, apply the hotfix, and then switch back, hoping not to disrupt your development workflow.

With worktrees:

  1. Create a new worktree for the production branch:
Terminal
git worktree add ../hotfix-production production
  1. Apply the hotfix in the new worktree:
Terminal
cd ../hotfix-production
# Apply your hotfix here
git commit -am "Apply critical hotfix"
git push
  1. Return to your feature work without any disruption:
Terminal
cd ../original-feature-work

Using multiple worktrees in these scenarios allows you to seamlessly switch contexts between different branches for testing, feature development, and urgent fixes, all without disrupting the mainline or other ongoing work.

For further reading on working trees in Git see the official Git documentation.

Graphite
Git stacked on GitHub

Stacked pull requests are easier to read, easier to write, and easier to manage.
Teams that stack ship better software, faster.

Or install our CLI.
Product Screenshot 1
Product Screenshot 2