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.css3 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:
- Create a new worktree for the
main
branch:
git worktree add ../main-branch main
- Switch to the new worktree and verify the implementation:
cd ../main-branch# Do your verification here
- 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:
- Create a new worktree for the new feature branch:
git worktree add ../feature-advanced-search feature-advanced-search
- 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:
- Create a new worktree for the
production
branch:
git worktree add ../hotfix-production production
- Apply the hotfix in the new worktree:
cd ../hotfix-production# Apply your hotfix heregit commit -am "Apply critical hotfix"git push
- Return to your feature work without any disruption:
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.