What is a Git working tree?

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.

Understanding the Git working tree

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.

Using the tree command to visualize the working tree

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:

sudo apt-get install tree

To install the tree command on macOS using homebrew run:

brew install tree

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

.
├── .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

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.

Adding a new worktree

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

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.

Git worktree cheat sheet

  • 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.)

Practical uses of multiple worktrees

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.

Quickly switch between branches for testing or comparison

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:
    
    

git worktree add ../main-branch main

2. **Switch to the new worktree and verify the implementation:**
   ```bash
cd ../main-branch
# Do your verification here
  1. Return to your original feature work:
    
    

cd ../original-repo-feature-new-ui


#### Isolate work on a new feature while keeping the main branch clean and deployable  
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:**
   ```bash
git worktree add ../feature-advanced-search feature-advanced-search
  1. Work on the feature in isolation:
    
    

cd ../feature-advanced-search

Develop your feature here without affecting the main branch


### Handle hotfixes or urgent changes on a production 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:**
   ```bash
git worktree add ../hotfix-production production
  1. Apply the hotfix in the new worktree:
    
    

cd ../hotfix-production

Apply your hotfix here

git commit -am "Apply critical hotfix" git push

3. **Return to your feature work without any disruption:**
   ```bash
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.