Installation
Diffdesk is a macOS app for Apple Silicon (ARM64), from macOS 13. Git is its only runtime prerequisite. Each release on GitHub Releases publishes diffdesk_<version>_darwin_arm64.zip, which holds Diffdesk.app, the MIT license and third-party notices, with its SHA-256 in checksums.txt. Homebrew and mise both install that archive and put diffdesk, the app’s executable, on PATH.
The app was called ghl until 0.4; see moving from ghl. Releases up to 0.2.0 shipped a browser CLI instead; see moving from 0.2.0.
Homebrew
Section titled “Homebrew”brew install --cask vmaerten/tap/diffdeskdiffdesk --versionThe cask installs Diffdesk.app in /Applications and links diffdesk into Homebrew’s bin, with ghl, the command’s former name. Name it in full: Homebrew 7 loads casks from a third-party tap only once trusted, and installing by full name trusts this one. After brew tap vmaerten/tap, a bare brew install --cask diffdesk first needs brew trust --cask vmaerten/tap/diffdesk.
The app is signed ad hoc, without Apple notarisation. Homebrew quarantines what it downloads, and Gatekeeper would then block the first launch; the cask removes that quarantine attribute after installing.
brew upgrade --cask diffdesk # follow stable releasesbrew uninstall --cask diffdesk # remove the app, keep its settingsbrew uninstall --cask --zap diffdesk # also remove its settings, caches and web dataInstall mise. If mise itself is on PATH, add this once to ~/.zshrc:
eval "$(mise activate zsh)"Open a new terminal and install globally:
mise use -g github:vmaerten/ghl@latestdiffdesk --versionThe built-in GitHub backend selects diffdesk_<version>_darwin_arm64.zip, verifies its digest from GitHub or checksums.txt, extracts it and puts Diffdesk.app/Contents/MacOS on PATH. No plugin or option is needed. mise downloads without the quarantine attribute, so the app opens without a Gatekeeper prompt. The app stays in mise’s install directory rather than /Applications, so it is opened with diffdesk, not from Spotlight or the Dock. mise puts only diffdesk on PATH, not ghl.
mise use installs and selects a version; shell activation updates PATH. Without activation, mise exec -- diffdesk runs the configured version. Shims are another option for scripts and IDEs: mise activate zsh --shims exposes them. Project configuration can override the global selection; check mise which diffdesk and type -a diffdesk if another diffdesk wins in PATH. Current mise defaults delay latest by 24 hours after publication; an exact version bypasses that delay, and latest excludes prereleases. mise ls-remote github:vmaerten/ghl lists published versions.
Pin, upgrade and roll back
Section titled “Pin, upgrade and roll back”Replace X.Y.Z with a published version, without the tag’s v prefix:
mise use -g github:vmaerten/ghl@X.Y.Zmise upgrade --no-prune github:vmaerten/ghlAn exact selection stays pinned during mise upgrade; select latest again to follow stable releases. --no-prune keeps the previous install, so rolling back is another mise use -g github:vmaerten/ghl@X.Y.Z.
Uninstall
Section titled “Uninstall”mise unuse -g --no-prune github:vmaerten/ghlmise uninstall --all github:vmaerten/ghlRemove any project selection too.
From the release page
Section titled “From the release page”A browser download of diffdesk_<version>_darwin_arm64.zip is quarantined, and Gatekeeper refuses to open the ad hoc signed app. Compare shasum -a 256 diffdesk_<version>_darwin_arm64.zip with the release’s checksums.txt, unzip it, then remove the attribute before the first launch:
xattr -dr com.apple.quarantine Diffdesk.appMove Diffdesk.app to /Applications and link Diffdesk.app/Contents/MacOS/diffdesk into a folder on PATH. Homebrew and mise do all of this for you.
After installing, upgrading or rolling back
Section titled “After installing, upgrading or rolling back”Stable builds installed through Homebrew or mise check for a newer stable release when the app starts. A banner at the bottom of the window offers Later to keep working, or Update…. Expand What’s new in… to read the proposed release’s changelog before deciding; if it has no notes, a link opens its GitHub release page. Confirm Update and Restart to install through the same manager and reopen the active comparison. You can also use Diffdesk → Check for Updates…. The banner shows installation progress and any failure, with Try Again when available. Its state and release notes stay available after reloading the review. Save any comment drafts before confirming: restarting discards unsaved drafts and other open tabs.
For mise installs, accepting an update selects latest in the global configuration and retains the previous install. Project version pins keep priority when launching from those projects. For Homebrew installs, the cask can briefly lag behind GitHub Releases; if the offered version is not installed yet, Diffdesk keeps running and asks you to retry later. A failed startup check stays silent; manual checks and installation failures report the error. Source builds, prereleases and manually downloaded copies do not offer automatic installation.
After upgrading or rolling back from the terminal, a running window keeps the version it started with: quit Diffdesk (Cmd+Q) to use the new one. Comments and Viewed stay in each checkout’s .git/ghl/state.json across upgrades, rollbacks and uninstalls. A release that resolves comments writes it as version 2 at the first change, which earlier releases refuse rather than reopen resolved comments: rolling back past it requires moving that file aside. Settings live in ~/Library/Application Support/Diffdesk/settings.json.
Moving from ghl to Diffdesk
Section titled “Moving from ghl to Diffdesk”Homebrew trusts a cask by name, so trust the new one before upgrading, or brew upgrade skips it:
brew updatebrew trust --cask vmaerten/tap/diffdeskbrew upgrade --cask diffdeskrm -rf "$(brew --caskroom)/ghl"- The upgrade replaces
ghl.appwithDiffdesk.app, and linksghlbesidediffdesk. It leaves an emptyghlentry thatbrew listshows andbrew doctorreports; the last line removes it. - With mise, the tool stays
github:vmaerten/ghl; aftermise upgrade, the command isdiffdesk. - Comments and Viewed stay in each checkout’s
.git/ghl/state.json. Settings are read from~/Library/Application Support/ghluntil the first change, then saved underDiffdesk. The sidebar and panel widths start over once. - A ghl window still open keeps running until you quit it.
Moving from the 0.2.0 browser CLI
Section titled “Moving from the 0.2.0 browser CLI”mise upgradeormise use -g github:vmaerten/ghl@latestmoves from the CLI to the app: same tool, new archive. Linux and macOS Intel are not served after 0.2.0; stay ongithub:vmaerten/ghl@0.2.0there.- When it starts, the app stops a 0.1 or 0.2 daemon still running on port 7777 and removes its lock folder. Open its reviews in the app with
diffdeskin each checkout. - Comments and Viewed carry over unchanged: the app uses the same
.git/ghl/state.json. --port,--no-open,--no-daemon,--idle,--print,--import-stateandGHL_PORTare gone.- A CLI installed from source by the 0.1 or 0.2
task install, a copy in~/.local/bin/ghl, or the earlier Node copy in~/.local/share/ghlwith its link, is removed when the app starts;task installalso replaces that copy. Any other file named~/.local/bin/ghlstays, andtask installrefuses to replace it. - Settings saved by the earlier
ghl Desktopapp are read until the first change, then saved underDiffdesk.