Have you ever been developing on a feature branch and needed to look at a separate branch on the same repo?

I have.

When this happens, I normally do one of two things:

  1. git stash my changes and change branches
    • This is annoying because it’s a lot of steps.
    • I also have to remember which stash to pop when I come back to this branch.
  2. Stage all my changes and store them in a work-in-progress commit
    • This is better than #1 but doesn’t let you view both branches simultaneously.
    • But it’s still annoying if you have files you haven’t staged yet and don’t want to stage yet.

Both these have drawbacks. For example, they don’t let me look at both branches at the same time in my text editor.

I learned about a git feature yesterday which solves this problem: git worktrees. Git worktrees allow you to check out a different branch of the same local repo under a different folder.

Here’s an example.

Assume I’m on main:

(main *) $ pwd
(main *) $ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   file.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

no changes added to commit (use "git add" and/or "git commit -a")

If I need to checkout other-branch, I create a worktree on that branch:

(main *) $ git worktree add ~/Downloads/other-branch-dir other-branch
Preparing worktree (checking out 'other-branch')
HEAD is now at 12aebd23 Add foo.txt

git worktree list shows that worktree:

(main *) $ git worktree list
/Users/james_simas/Downloads/worktree-example  91db89fb [main]
/Users/james_simas/Downloads/other-branch-dir  12aebd23 [other-branch]

If I switch to that directory, it contains a copy of my repo and has the other-branch checked out:

(other-branch) $ pwd
(other-branch) $ git status
On branch other-branch
nothing to commit, working tree clean

When I’m done with the worktree, I can remove it like this:

(main *) $ git worktree remove /Users/james_simas/Downloads/other-branch-dir

It’s now gone:

(main *) $ git worktree list
/Users/james_simas/Downloads/worktree-example  91db89fb [main]

I could also just rm -rf ~/Downloads/worktree-example and then run git worktree prune to remove the worktree.