Huon on the internet

magit-insert-worktrees improves status buffers

By Huon Wilson13 Dec 2025

The Magit package for Emacs is my Git UI of choice, and git worktrees are very convenient. They mesh up particularly well by adding the built-in magit-insert-worktrees to magit-status-sections-hook. With this, the magit status buffer shows a summary of the branch/HEAD/path of all worktrees, and allow jumping between them in a flash.

1
2
;; Show all worktrees at the end of the status buffer (if more than one)
(add-hook 'magit-status-sections-hook #'magit-insert-worktrees t)

A magit status buffer with all the usual features, plus the new ‘Worktrees’ section at the end: the outlined row with an absolute path is the worktree for the current status buffer, and the other two are elsewhere on disk. Hitting RET on any worktree switches to it.

Worktrees

Git has a feature called worktrees, which are a nifty way to do work in parallel: different branches checked out in different directories, but all sharing a single .git directory. This means less disk space used on duplicate .git clones, but, more usefully, data like branches & stashes is shared.

There’s lots of ways to use worktrees, and they’re especially handy in the age of AI agents. At the most basic level, they’re useful for working concurrently, like reducing context switching when balancing deep projects, code reviewing, and small fixes.

I know some people like to create a new worktree for each branch they work on, and then remove them once finished (or get their agents to do so). I personally generally have fixed long-lived worktrees0 that I cycle branches through as required: for my main work repo, I’m up to name, name2, …, name5 at the moment… and if I ever need a 6th one, I’ll just create it.

Finding the worktrees

In either case, I find it annoying to keep track of what worktrees are ‘live’. There’s workable solutions, but they’re a bit of friction:

The magit status buffer is the entry-point to a Git repo, and surfaces a lot of information that’s handy to have immediately available, in collapsible sections, things like diffs of any uncommitted and branch summaries. It reduces friction by making git status/git diff/… automatic and interactive, and is customisable.

I wanted to apply that mindset to worktrees too, and so, recently, started writing my own worktree section inserter… but then thought to double check the Magit source code for anything similar, and found exactly what I wanted1!

Magit has a builtin magit-insert-worktrees function that inserts a section summarising all worktrees (or nothing, if there’s only one worktree). It’s interactive: hitting RET on any worktree shows the magit status buffer for it.

It’s not used by default, so it needs to be explicitly enabled by adding to the hook that the status buffer executes to show all the sections. My init files now include:

1
2
;; Show all worktrees at the end of the status buffer (if more than one)
(add-hook 'magit-status-sections-hook #'magit-insert-worktrees t)

My status buffers now look like the screenshot above. Yay!

  1. I’ve settled on long-lived worktrees for two reasons:

    1. IME many code-bases have at least a little bit of static setup that’s intentionally not tracked in Git (like initialising an .env file from an .env.example file), and starting a new worktree requires redoing this… this can be solved with scripts, or just be side-stepped.
    2. I have an (arguably bad) habit of taking notes, leaving reference data and/or creating ad-hoc scripts in untracked files in a worktree, and sometimes want to return to them and persist them later (commit, or paste into a issue tracker, or similar), so creating then deleting worktrees risks accidentally losing them.

  2. This function appears to have existed since 2016, but not be mentioned in the manual, so I submitted an addition

This article is from a human: I used no AI to write it.