A modern, native CVS client for macOS, written in SwiftUI. A spiritual
successor to the classic MacCVS / cvsgui — which
was a PowerPC/Carbon app that has been unrunnable since macOS Catalina removed
Carbon and 32-bit support. MacCVS is a fresh, universal (Apple Silicon + Intel),
notarized app that drives your existing cvs command-line tool.
CVS is old, but plenty of long-lived projects still live in it. The good graphical clients were left behind years ago:
- MacCVS (cvsgui) — Carbon/PowerPlant, dead since Catalina.
- gCVS — GTK2 + libglade, a multi-day dependency-porting project on modern macOS.
- TkRev/TkCVS — still works (Tcl/Tk), but not a native Cocoa app.
MacCVS is a small native app that wraps the cvs CLI you already have and gives it
a fast, modern macOS front end.
- Finder-style column browser for the directory hierarchy (real
NSBrowser). The first column is a project switcher listing the CVS working copies you've opened; right-click to Forget one or reveal it in Finder. - File list showing every file's CVS status and revision, with sortable Name / Status / Rev columns.
- Instant local change detection. A file's modified state is determined by
comparing its modification time to the timestamp CVS recorded in
CVS/Entries— exactly howcvsdecides — with no network round-trip. An FSEvents watcher flips files to Modified the moment you save. - Instant diffs. When a file changes, its base revision is fetched in the background and cached, so opening a diff is immediate (no waiting on the server).
- Native side-by-side diff window (see below): line- or word-level highlighting, a unified-view toggle, a draggable center divider, and multi-file diffs in one window. The window auto-sizes to fit the content.
- Core CVS operations: Update, Commit (with a per-file picker), Diff, Log,
Add, Revert (
update -C). - History window:
cvs logis parsed into a clean timeline of revisions (revision, author, date, ± line counts, message). A Show diffs toggle loads the visual diff each revision introduced, inline and on demand. - View filters: hide dot-files and non-CVS files by default, toggle from the View menu (⌘⇧. and ⌘⇧U).
- Remembers your last project and directory across launches.
- Automatic updates: once a day MacCVS checks GitHub Releases; if a newer build exists it offers to update, then downloads it, verifies it is notarized, and relaunches into the new version. Also available on demand from the app menu (MacCVS ▸ Check for Updates…).
The diff viewer is a standalone, resizable window. Its data model and side-by-side
visual style are adapted from swifty-diff
(MIT); MacCVS adds a cvs diff parser, a real window, a unified-view toggle, a
draggable divider, and word-level (intra-line) highlighting.
- Side by side / Unified toggle.
- Line / Word toggle — Word highlights only the changed tokens within a line.
- Drag the center divider to rebalance the two panes; each pane scrolls its own long lines while vertical scrolling stays in sync.
- Select several modified files and Diff them all into one window.
- macOS 14 (Sonoma) or later.
- Nothing else — MacCVS bundles its own
cvs. You do not need to install CVS. A self-contained universal CVS 1.11.23 client ships inside the app (Contents/Resources/cvs, linking only the system libraries), and MacCVS always uses that one, never the system'scvs. See THIRD-PARTY.md andbuild-cvs.shfor how it's built.
Download the latest notarized build from the Releases page, unzip, and drag MacCVS.app to your Applications folder.
git clone https://github.com/johnbuckman/MacCVS.git
cd MacCVS
swift build -c release # or: ./build.sh (assembles a universal .app)build.sh produces a universal (arm64 + x86_64) MacCVS.app. Notarized releases
are produced with release.sh (Developer ID signing + notarytool).
MacCVS accepts a few command-line options, so it can be scripted or used as a
graphical diff viewer by other programs. Invoke the executable inside the bundle
(or open -a MacCVS --args …):
MacCVS=/Applications/MacCVS.app/Contents/MacOS/MacCVS
"$MacCVS" /path/to/workingcopy # open a working copy
"$MacCVS" --open /path/to/workingcopy
"$MacCVS" --diff FILE... # CVS diff (repo vs working) of one or more files
"$MacCVS" --diff lib/a.tcl lib/b.tcl lib/c.tcl # several files, one window
"$MacCVS" --compare LEFT RIGHT # visual diff between two arbitrary files
"$MacCVS" --help--diff accepts any number of files and shows all of their CVS diffs together
in one window. In --diff/--compare mode MacCVS shows only the diff window
(no main window) and quits when it is closed — so another program can call it to
display a diff, e.g. as a git difftool (which passes two files to compare):
git config --global difftool.maccvs.cmd \
'/Applications/MacCVS.app/Contents/MacOS/MacCVS --compare "$LOCAL" "$REMOTE"'
git difftool -t maccvsMacCVS is a thin GUI over the cvs CLI — it never re-implements the CVS protocol.
CVSServiceexecs the bundledcvsdirectly viaProcess(no shell), and computes local modified-state fromCVS/Entriestimestamps.WorkingCopyStoreis the app state (@MainActorObservableObject): the file list, the FSEvents watcher, the base-revision prefetch cache, and all operations.DirectoryColumnBrowserwrapsNSBrowserfor the column view + project switcher.SwiftyDiffholds the diff model, the unified-diff parser, word-level diffing, and the SwiftUI diff window.
MacCVS is licensed under the GNU General Public License v3.0 (see LICENSE).
It bundles GNU CVS 1.11.23 (GPL-2-or-later) as a separate executable, and the diff viewer adapts the model and visual style of swifty-diff by Michael Neale (MIT). See THIRD-PARTY.md.

