Checking state before risky commands
Before you rebase, switch branches, or reset, run git status to find out whether the working tree has uncommitted edits. If it does, commit or stash them first so nothing gets overwritten.
Git · Concept
The working tree is the directory of real, checked-out files that you edit. It usually starts from the tree of the HEAD commit and also holds any local changes you have not committed yet.
Last updated
Git keeps history as compressed objects inside the repository, but you work on ordinary files on disk. When you check out a branch or commit, Git writes that commit's tree into your working directory and records it in the index. After that, you can edit files freely. Git finds your changes by comparing the files on disk with the index and with HEAD. When the files match the commit HEAD points to, the working tree is clean. Once you make edits that are not committed, it is dirty. A non-bare repository has one main working tree. git worktree can attach more working trees, and each one has its own HEAD and index.
#!/usr/bin/env bash
set -euo pipefail
cd "$(mktemp -d)"
git init -q demo && cd demo
git config user.email you@example.com
git config user.name You
echo 'hello' > greet.txt
git add greet.txt
git commit -qm 'initial'
git status --short # nothing printed: working tree is clean
echo 'world' >> greet.txt # edit a file on disk
git status --short # ' M greet.txt' -> working tree differs from index
git diff # shows working tree vs index
git restore greet.txt # copy the index version back into the working tree
git status --short # clean again
git rev-parse --show-toplevel # prints the root of the working treeThe script edits a committed file, uses git status and git diff to show that the working tree is now dirty, and then runs git restore to make it clean again.
Before you rebase, switch branches, or reset, run git status to find out whether the working tree has uncommitted edits. If it does, commit or stash them first so nothing gets overwritten.
An urgent fix comes in while you are halfway through a refactor. Use git worktree add to create a second working tree on another branch, so you do not have to disturb the files you are already editing.
A build script runs from somewhere deep in the project. It can use git rev-parse --show-toplevel or :/ pathspecs so its paths are resolved from the root of the working tree.
HEAD names the commit you are on, usually through the current branch. The index is a stored snapshot that will become the next commit. The working tree holds the editable files on disk. It normally matches HEAD's tree plus any uncommitted edits you have made.
Follow-up: What do git diff, git diff --cached and git diff HEAD each compare? git diff compares the working tree with the index. git diff --cached compares the index with HEAD. git diff HEAD compares the working tree directly with HEAD.
A working tree is clean when its contents match the revision referenced by the current head. It is dirty when it has modifications that have not been committed to the current branch. git status shows this by listing staged changes, unstaged changes and untracked files.
Follow-up: Why can git status look clean even though untracked build files exist? Files that match .gitignore patterns are ignored, so git status does not list them. You can see them with git status --ignored.
Yes, both. A bare repository has no working tree, and a normal repository has one main working tree. git worktree add can attach more linked worktrees, each with its own HEAD and index, while they all share the same object database and refs.
Follow-up: Why does Git refuse to check out the same branch in two worktrees by default? If two working trees had the same branch checked out, a commit in one would move that branch under the other and leave it out of sync. git worktree add only allows it with --force.
indexHEADcheckoutcleandirtyworktreebare repositorygitfile