Home / Alt manpages / git-worktree(1)

  • git-worktree(1)
  • User command
  • linux

Use Git Worktrees for a Clean Parallel Branch

You will finish with a second checkout of the same repository, on its own branch and at its own path. That lets you inspect or fix another branch without stashing the files in your current working tree. The examples match Git 2.43.0, which is the installed version here.

Allow about fifteen minutes. You need Git, a repository with at least one commit, and write access to the directory where the new worktree will live. These are ordinary user commands. No example needs sudo; using elevated privileges can leave the worktree owned by root and cause a later cleanup problem.

1. Check the repository before adding a tree

Run this from the existing repository. It does not change files:

$ git --version
git version 2.43.0
$ git status --short
$ git branch --show-current
main

An empty git status --short is not required. A worktree is separate, so your uncommitted files can remain where they are. However, record that you are in the intended repository and choose a destination outside its current directory. The destination must not already contain unrelated files.

Checkpoint: if git branch --show-current prints nothing, the current tree has a detached HEAD. You can still add a worktree, but use an explicit branch or commit in the next step so the result is unambiguous.

2. Add a worktree on a new branch

Choose a branch name and a sibling directory. This creates the branch from the current HEAD and checks it out in the new directory:

$ git worktree add -b fix/example ../repo-fix-example
Preparing worktree (new branch 'fix/example')
HEAD is now at abc1234 Example commit message

The commit abbreviation and message will differ. The final path component does not have to match the branch name because -b makes the branch choice explicit. The new worktree shares the repository data, but it has its own HEAD, index and checked-out files. Changes made in one tree do not appear as uncommitted changes in the other.

Verify both the path and branch before starting work:

$ git worktree list
/path/to/repository       abc1234 [main]
/path/to/repo-fix-example  abc1234 [fix/example]
$ git -C ../repo-fix-example status --short --branch
## fix/example

If the branch already exists, use git worktree add ../repo-fix-example fix/example instead. Git refuses if that branch is already checked out in another worktree. That safeguard prevents two indexes from silently competing over one branch.

3. Work in the new tree

Change directory explicitly, then use normal Git commands:

$ cd ../repo-fix-example
$ git status --short --branch
## fix/example
$ git log -1 --oneline
abc1234 Example commit message
$ git switch --show-current
fix/example

Commit on fix/example as usual. The original checkout can continue to hold a different branch. When you need to compare them, use git -C PATH ... from a common parent directory, or open separate terminal sessions. Keep the path in a shell variable if it is long:

$ WORKTREE_PATH="../repo-fix-example"
$ git -C "$WORKTREE_PATH" status --short --branch

Do not assume that .git is a directory in a linked worktree. It is normally a file pointing at private administrative data under the main repository's .git/worktrees directory. Let Git resolve that layout rather than editing those files by hand.

4. Inspect all trees in a script-friendly format

The normal list is convenient for people. For a script or a diagnostic note, use porcelain output, whose labels are stable across Git versions:

$ git worktree list --porcelain
worktree /path/to/repository
HEAD abc1234...
branch refs/heads/main

worktree /path/to/repo-fix-example
HEAD abc1234...
branch refs/heads/fix/example

Each record starts with worktree; a blank line ends the record. A detached tree has a detached line instead of branch. Add -z when paths may contain newlines, because it changes record lines to NUL-terminated output. Do not parse the aligned columns of the default output in a script.

5. Lock a tree that may disappear temporarily

If the new worktree is on a removable disk or network share, lock its administrative record before unmounting it:

$ git worktree lock --reason 'external SSD is offline between sessions' ../repo-fix-example
$ git worktree list --verbose
/path/to/repo-fix-example  abc1234 [fix/example]
        locked: external SSD is offline between sessions

Locking prevents automatic pruning and also prevents the worktree from being moved or removed until it is unlocked. This is metadata protection, not encryption or access control. When the path is available again and you are ready to manage it normally:

$ git worktree unlock ../repo-fix-example
$ git worktree list --verbose

Checkpoint: if a lock blocks a planned move or removal, unlock the tree first. Do not jump straight to repeated -f options unless you have checked the path and understand what will be discarded.

6. Remove the linked tree safely

Finish or copy out anything you need, then check for changes before removal:

$ git -C ../repo-fix-example status --short
$ git worktree remove ../repo-fix-example
$ git worktree list

Git removes a clean linked worktree. A clean tree has no modified tracked files and no untracked files. The main worktree cannot be removed. If removal is refused, inspect the status and either commit or copy the work elsewhere. Only use the destructive override after checking the exact path:

$ git -C ../repo-fix-example status --short
$ git worktree remove --force ../repo-fix-example

Warning

--force removes an unclean worktree and can discard uncommitted files. A locked worktree needs --force twice, so stop and decide whether the lock or the data is meant to survive before using that form. There is no Git undo for files discarded by forced removal. A committed branch remains in the repository, and you can recreate its worktree later with git worktree add PATH fix/example.

7. Repair a path moved outside Git

Use git worktree move when relocating a linked tree, because it updates the administrative connection:

$ git worktree move ../repo-fix-example ../repo-fix-renamed
$ git worktree list
/path/to/repo-fix-renamed  abc1234 [fix/example]

The main worktree and linked worktrees containing submodules cannot be moved with this command. If a directory was moved manually, run git worktree repair from the moved worktree, or run it from the main worktree with each new linked path as an argument. Do not edit .git/worktrees by hand unless you are recovering from a situation Git cannot repair.

Done means

  • The second path appears in git worktree list with the intended branch.
  • The original and linked trees have independent HEAD and index state.
  • Any removable or network-backed tree was locked with a useful reason before it went offline.
  • You checked status before removal and did not use --force casually.
  • The linked tree was removed cleanly, or its path was repaired after a manual move.