# 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](/content/docs/command-reference?utm_source=guidesCallout/index.html).

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:

```bash
sudo apt-get install tree
```

To install the tree command on macOS using homebrew run:

```bash
brew install tree
```

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

```bash
.
├── .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>`:

```bash
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:**
   ```bash
git worktree add ../main-branch main
```
2. **Switch to the new worktree and verify the implementation:**
   ```bash
cd ../main-branch
# Do your verification here
```
3. **Return to your original feature work:**
   ```bash
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
```
2. **Work on the feature in isolation:**
   ```bash
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
```
2. **Apply the hotfix in the new worktree:**
   ```bash
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](https://git-scm.com/docs/git-worktree).
