Free, open-source diff & merge app for macOS: compare text, pasted snippets, images, and folders, resolve 3-way merges, and browse git history. Native SwiftUI + Liquid Glass.
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗A free, open-source macOS app for comparing and merging text, pasted snippets, images, and folders — with three-way merge and git built in.
differentialis.app · Download · Changelog · Sponsor
Written in SwiftUI with Apple's Liquid Glass. The diff, merge, and git engines have no third-party dependencies; Sparkle is the lone dependency, used only for in-app updates.
Grab the latest .dmg from the Releases
page, open it, and drag Differentialis onto Applications.
The build is signed with Developer ID and notarized by Apple, so it opens without Gatekeeper
warnings. Each published release automatically gets a signed, notarized .dmg attached by the
Release DMG workflow ( runner + Xcode 26).
Release history lives in the .
macos-26After that first install, you won't need the DMG again — Differentialis updates itself: Check for Updates… (or the update banner) downloads, verifies, installs, and relaunches the new version in place.
Text diff — a from-scratch Myers diff engine with character-level intra-line highlights, side-by-side and unified layouts, exact or whitespace-insensitive matching, line-ending/final-newline diagnostics, change bars, collapsible unchanged regions, next/previous-change navigation, and live insertion/deletion stats.
Paste Text — compare snippets without saving files: paste or type into two side-by-side editors (⌘T) and the diff updates live as you edit, with synced scrolling and line numbers. Copy any change from one side to the other (⌥⌘→ / ⌥⌘←), with full undo, or flip to the split/unified Diff view.
Image diff — four comparison modes with ⌘1–⌘4:
Folder diff — recursive scan classifying every file as Added / Removed / Modified / Identical, with changes-only, name, and status filters plus click-through to the right diff for each file.
3-way merge — base / left / right with an editable result, per-hunk take left / right / both / base, content and line-ending conflict resolution, and save-merged output.
Git integration — open any repository to browse its commit history or flip to a changed-files view with correct reference/index/working-tree snapshots, grouped by folder and filterable by name, extension, or status. A persistent Projects sidebar keeps your opened repositories one click away. Uses the system git, no libgit2.
Custom Comparison — a Liquid Glass popover to compare any Reference or Commit (pick from history or paste a commit hash) against the Working Copy, another Reference, or Commit — with swap, and Save to revisit named comparisons later.
Appearance & themes — Light, Dark, or Auto (follows the system), with a theme per appearance: Differentialis, Mariana, Monokai, One Dark, Solarized, and GitHub. Build your own in the theme editor, import JSON or .tmTheme color schemes, and pick the code font family and size (⌘+ / ⌘− / ⌘0, or pinch). All in Settings (⌘,).
Liquid Glass throughout — glass toolbars, mode switchers, popovers, and panels native to macOS 26 Tahoe.
In-app updates — a quiet banner (Skip / Later / Update) offers new versions and installs them in place — download, EdDSA-verify, swap, and relaunch — without leaving the app, plus Check for Updates… in the app menu. Powered by Sparkle reading an appcast attached to the latest GitHub release.
Every command is in the menu bar, and Help ▸ Keyboard Shortcuts (⌘/) shows the full cheat sheet.
| Action | Shortcut |
|---|---|
| New Text / Image / Folder comparison | ⌘N / ⇧⌘N / ⌥⌘N |
| New Pasted Text comparison | ⌘T |
| Open Repository | ⌘O |
| Next / previous change | ⌘] / ⌘[ |
| Toggle Split / Unified | ⌘U |
| Pasted text: copy change to B / A | ⌥⌘→ / ⌥⌘← |
| Image: Two-Up / One-Up / Split / Difference | ⌘1 / ⌘2 / ⌘3 / ⌘4 |
| Code font size: bigger / smaller / reset | ⌘+ / ⌘− / ⌘0 |
| Settings | ⌘, |
| Go to Welcome | ⇧⌘0 |
| Keyboard Shortcuts | ⌘/ |
brew install xcodegen.# 1. Generate the Xcode project from project.yml
xcodegen generate
# 2a. Open in Xcode and hit Run
open Differentialis.xcodeproj
# 2b. …or build & launch from the command line
xcodebuild -project Differentialis.xcodeproj -scheme Differentialis \
-configuration Debug -derivedDataPath build build
open build/Build/Products/Debug/Differentialis.app
A thin differentialis shell script is bundled inside the app and opens a diff from any
directory. Install it from the app menu: Differentialis ▸ Install Command Line Tool… — one
password prompt, then it's on your $PATH forever. (The menu item toggles to Uninstall…
once installed.)
Then:
differentialis <path> # open a git repository (error if not one)
differentialis fileA.txt fileB.txt # compare two files (auto-detects text/image/folder)
differentialis folderA folderB # folder diff
differentialis base.txt mine.txt theirs.txt # 3-way merge
differentialis --wait fileA.txt fileB.txt # …and wait until that comparison is closed
Paths are resolved against the current directory. The launcher talks to Differentialis by bundle id
(app.differentialis.Differentialis), so it resolves to the registered release install — not a
stale Debug build — and works whether the app is already running or not.
Add --wait and the launcher blocks until you're done in the app, which is what git's tools need.
Put this in ~/.gitconfig:
[diff]
tool = differentialis
[difftool "differentialis"]
cmd = differentialis --wait -- \"$LOCAL\" \"$REMOTE\"
[merge]
tool = differentialis
[mergetool "differentialis"]
cmd = differentialis --wait --output \"$MERGED\" -- \"$BASE\" \"$LOCAL\" \"$REMOTE\"
trustExitCode = true
git difftool opens each file and moves to the next one when you click Done (or close the
comparison). git difftool --dir-diff opens one folder comparison. Added and deleted files show
their missing side as absent.git mergetool opens a 3-way merge whose Save writes the result straight to the conflicted
file (as UTF-8). Once no conflict markers are left, saving also closes the merge and git marks the
file resolved; a save that still has markers keeps the merge open. Cancel Merge (or closing
without a resolved save) leaves the file unresolved.--wait existed, uninstall and reinstall it from the app menu.You can also launch straight into a comparison with open directly:
open Differentialis.app --args fileA.txt fileB.txt # text or image diff
open Differentialis.app --args folderA folderB # folder diff
open Differentialis.app --args base.txt mine.txt theirs.txt # 3-way merge
open Differentialis.app --args /path/to/git/repo # repository browser
Differentialis/
├── Diff/ Myers diff (generic), line diff, char highlights, diff3 merge — pure Swift, unit-tested
├── Git/ system-`git` wrapper (Process): log, diff, blobs, refs, changesets
├── Models/ Comparison + ComparisonSource (file / git blob / working copy), saved-comparison store
├── Features/ Text · Image · Folder · Merge · Repo views
└── DesignSystem/ Liquid Glass components, theme, the app mark
The diff and merge engines have no dependencies — MyersDiff powers both line- and character-level diffs, and a diff3 algorithm drives the 3-way merge. Git is driven through the system git binary, so there is nothing to vendor.
xcodebuild -project Differentialis.xcodeproj -scheme Differentialis test
Covers Myers and line diff behavior, intra-line highlights, three-way merge, copying changes between pasted texts, folder scanning and filtering, git status parsing, and real temporary-repository checks for reference/index/working-tree comparisons.
CI runs the same suite on a macOS 26 runner for every push to main and
every pull request, and checks the README and website: every local link and image resolves, and the
site's structured data, FAQ, and sitemap are valid (python3 scripts/check-site.py runs that check
locally).
The full, prioritized backlog is in docs/ROADMAP.md. Highlights:
diff-style command-line companion~/.gitconfig entries for you is still planned.MIT © Jenny Speelman