Worktrees

The default behaviour of git clone is to checkout a single working copy of the repository with the Git repository itself nested under the .git directory. Git worktrees allow us to checkout multiple branches as separate working copies that share a single underlying repository. This can be useful when maintaining multiple branches of the codebase where it's often necessary to cherry-pick patches across branches.

Managing worktrees

Each repository is considered to have a main worktree and a series of linked (added with add) worktrees.

  • list lists worktrees.
  • add <path> [<commit-ish>] adds a new worktree and checks out the specified reference.
  • prune removes unlocked worktrees that no longer exist from the .git/worktrees file.
  • move <name> <path> relocates a worktree.
  • remove <worktree> removes a clean working tree.
  • repair [<path>...] can be used after a move of a worktree to recover it.

Locking

Worktrees on remote network shares or removable volumes can be locked to prevent Git from performing maintenance on them.

  • lock [--reason <reason>] <name> locks the named worktree.
  • unlock <name> unlocks it.

Workflow

For instance, with Moodle, where master tracks the currently active development branch and stable versions are in the MOODLE_*_STABLE branches:

git clone https://github.com/moodle/moodle.git master
cd master/
git worktree add -b MOODLE_31_STABLE ../MOODLE_31_STABLE origin/MOODLE_31_STABLE

This would yield two worktrees:

  • master would track origin/master.
  • MOODLE_31_STABLE would track origin/MOODLE_31_STABLE, using the local branch MOODLE_31_STABLE.

Backlinks