Every checkout, every worktree,
and what each of them changed

One page over a directory full of git repositories. Two dozen worktrees stop being two dozen terminals.

Loading… All downloads
Finding the latest release…
Grove: the repos, the worktrees of one of them, the scope column, the file tree, and a diff with syntax colours

Three panes

Each one narrows what the next one shows

A directory full of clones is how the work is actually laid out — the main project next to the libraries it uses next to two dozen plugin repos. Which of them is interesting changes by the hour.

01 — REPOS

Every repository

Sorted by how much is checked out, then by when it was last worked in. Not when it was last read: scanning a repo touches .git, and a dashboard that made every repo look freshly used would be worse than none.

02 — WORKTREES

The checkouts of one

Branch, distance from the base branch, how much is uncommitted. Linked worktrees are found wherever they live, a sibling directory included.

03 — VIEWER

What it changed

What is known about the checkout in the head, and its diff below. Every pane refreshes itself — commit in a terminal and the diff follows without a click.

Nothing compares against a hardcoded main. The base is the branch checked out in the main repo, so putting a release branch there makes every number and every diff follow it, with no flag to remember.

The diff

What to diff, which file, and the diff

A worktree has several honest answers to “what changed here”, and it needs all of them. Each is one entry in the scope column, carrying its own file count and +/.

Committed and uncommitted, together

Not separate views. A file is listed once and marked with where its change lives, because “what is in this worktree” is the question and whether a line is committed yet is a detail of it.

How far a commit has travelled

unpushed — still yours to rewrite. not in base — pushed, but the base branch has not got it. landed, and just history now.

A markdown file rendered before and after, side by side, with the reworded words marked
A README rendered before and after — matched block by block, then word by word, so a reworded sentence shows the words that moved and not the paragraph.
Two filters open, each matched term marked in its own colour
Every column filters itself. The query is whitespace-separated terms in any order, and each term is marked in the colour it wears in the input, so the eye can tell which word found what.

How it works

It reads git, and it tells you the truth about it

Grove never starts, stops or reconfigures anything. It runs the same commands you would run yourself, on a loopback port nothing outside the machine can reach, and shows you what they said.

No configuration

Point it at a directory of repositories. It needs git on the path and nothing else — no daemon, no index, no account, no telemetry.

Lazy and per repo

With dozens of repositories, refreshing all of them on a timer would be waste. A repo is scanned when a request finds its cache stale.

One network request

Once a day it asks GitHub whether a newer release exists, and says so if there is one. No identifier is attached, nothing is downloaded, nothing is installed — -no-update-check turns even that off.

Nothing else leaves the machine

No telemetry, no analytics, no account. Your repositories are read where they are and the page is served to you alone.

Get it

Download

macOS and Windows for the app. Linux gets the command, which serves the same dashboard to a browser.

With Homebrew, on macOS

Four lines, and brew upgrade keeps it current afterwards.

brew tap programmfabrik/grove https://github.com/programmfabrik/grove
brew trust --cask programmfabrik/grove/grove
brew install --cask grove
xattr -dr com.apple.quarantine /Applications/Grove.app

Neither of the last two is optional. Homebrew refuses a cask from a third-party tap until you trust it, and it quarantines what it downloads just as a browser does — without the last line the first launch offers to move Grove to the Bin.

As a command, anywhere Go runs

go install github.com/programmfabrik/grove@latest
cd ~/src && grove          # http://localhost

Or a file

Loading…

Opening it the first time

These builds are not notarised by Apple, so macOS quarantines them however they arrive — downloaded or installed by Homebrew alike — and Windows SmartScreen warns about a program it has not seen. Neither says anything about the program; both are the cost of an unsigned build, and notarising it is the real fix.

macOS — with Grove.app in Applications, before you open it:

xattr -dr com.apple.quarantine /Applications/Grove.app

Open it without that and the dialog says macOS could not verify Grove is free of malware, offering Done and Move to Bin — there is no "Open Anyway" in it. If you have already met it, the app is fine: run the line above and open it again.

WindowsMore info → Run anyway.