Skip to content

Releases: olegklimakov/fretwire

Fretwire 0.7.0

Choose a tag to compare

@olegklimakov olegklimakov released this 28 Aug 15:36

The seventh beta is about reading a diff, and about the rail knowing what it
draws. A changed line says which characters changed rather than tinting the
whole row, and the diff is finally text you can select, copy and scroll sideways
through. On the rail, the tooltip that was written for a badge and never once
appeared is replaced by a card that says which repository, which checkout and
which branch — and a repository whose own icon is no use at 30pt can be told to
show letters instead.

New

  • Only what changed is marked — a changed line used to tint end to end, which
    says a line is different without saying how. Each deletion is now compared
    against the addition it faces, at word granularity, and only those characters
    carry the mark. A pair that shares less than 30% of its characters keeps the
    plain whole-row tint: below that the two lines are not a rewrite of each other,
    and marking them word by word produces confetti rather than a reading.
  • Diff lines can be selected and copied — press, Shift, ⌘, drag, ⌘A, ⌘C and a
    context menu, in the diff as in a list. The unit is the line, so the two halves
    of a split pair are picked apart rather than taken together, and a range runs
    along the column it is drawn in. What lands on the clipboard is plain: no +
    and - markers, no line numbers — the text as it will be in the file.
  • Long lines can be reached — the diff body scrolls both ways, and in the
    split view each pane scrolls horizontally inside its own half instead of
    pushing the AFTER side off the window. The content width is measured rather
    than guessed, because a lazy stack only measures the rows currently on screen
    and a long line further down would otherwise not widen anything.
  • A card for a rail badge — the rail draws two or three letters per tab, and
    the tooltip written to explain them never appeared. It is a card now, shown
    while the pointer rests on a badge: the repository, the checkout, the branch
    and the path on disk, one fact per line. It takes no mouse events at all —
    switching repositories stays one click, where a popover's click-outside-to-
    close ate the first one — and it follows the pointer from badge to badge as a
    swap rather than a blink. VoiceOver reads the same facts, so two worktrees of
    one project stop being two elements with the same name.
  • A repository's icon can be turned down — the rail draws whatever a
    repository ships, and some of those are no use at 30pt: a white mark on white,
    or the one icon every service in a monorepo carries. The customize sheet now
    asks the question outright — repository icon, or letters — and appears only
    when there is an icon to turn down, because otherwise letters are not a choice
    but the only answer. The preview shows whichever badge is chosen.
  • Column widths belong to the tab — dragging AUTHOR wide enough for a
    monorepo full of feature/PROJ-1234_… branch names used to widen every other
    repository too. Widths are per repository now: they are a fit to what the rows
    in front of you hold, not a preference that travels. Which columns to show
    stays app-wide — that one is a reading preference, and it follows the reader.
  • A branch checked out elsewhere goes to its worktree — selecting such a
    branch was answered with git's refusal and an Open Worktree button to press
    afterwards. You had said where you wanted to go; the app made you say it twice.
    git allows a branch in exactly one working tree, so "check it out here" has no
    meaning for one — the app goes to the directory instead, from the toolbar menu,
    the sidebar, the context menus and ⏎ alike. The refusal still appears when the
    app's refs were stale, and then it offers what that path can still take: open
    it if the worktree is there, prune it if git's record has outlived it, and
    nothing at all if it is there but unreadable, where pruning would throw a live
    association away to fix a permissions problem.

Fixed

  • A tag whose name a branch also carries was unreachable — Checkout in the
    tag's own menu asked git for the bare name, and git calls a name held by both a
    tag and a branch ambiguous and picks the branch. The app then went further and
    sent it to whichever worktree held that branch. A tag checkout detaches HEAD,
    so it now asks for refs/tags/<name>, which resolves to one thing.
  • The traffic lights rode above the row they label — macOS centres the window
    buttons in the 32pt titlebar it draws itself, and the row beside them is 44pt,
    which left the three buttons 6pt above the repository name and path. They sit
    on the row's centre line now, and are put back there after every resize and
    full-screen transition, where AppKit re-runs its own layout.
  • Switching between open tabs was slow — the rail wrapped the switch in an
    animation so its accent marker could travel between icons, and that transaction
    reached the pane as well: the window's whole contents crossfaded over a 0.28 s
    spring on every click. ⌘⇧] and ⌘⇧[, which animate nothing, were already
    instant — the same switch, one of them slow. The pane opts out now and the
    marker keeps its travel. What is left is 84 ms for 240 commits, and 122 ms for
    the same history carrying 300 branches; nothing in a switch runs git.

Requirements

  • macOS 14 or later.
  • A git — whichever comes first on your login shell's PATH, else Apple's. With
    none installed at all, the Welcome screen says so once, with the command that
    fixes it.

Not here yet

  • A command palette.
  • Dragging a commit onto a branch. The rebase editor covers reordering a range;
    history by drag-and-drop is a separate decision, and it hasn't been made.

During the beta

Free, for any use. Licensing starts at 1.0: free for personal projects, paid per
seat for commercial use — see the EULA.

The app updates itself — each update is checked against a signature before it is
applied. Settings ▸ Updates decides how much of that happens on its own. Bug
reports and requests go to the issue tracker.

Fretwire 0.6.0

Choose a tag to compare

@olegklimakov olegklimakov released this 25 Aug 18:35

The sixth beta is about the history row as a place to act from. Two things that
lived somewhere else moved onto the commit itself: the force push that every
rewrite in its menu warns will be needed, and the worktree already checked out
at that commit — a checkout that costs nothing, because the directory is
standing there on it. And a linked worktree stops posing as a project of its
own: its tab nests under the project it belongs to, smaller, with a branch
glyph, and it is the repository that goes into recents.

New

  • Force push from the history — a commit's menu offers four ways to rewrite
    what is under it, and each one says the same thing afterwards: this will need
    a force push. The push itself was a trip away, to the toolbar or the remote
    hub. Force Push <branch> now sits on the tip of any branch whose
    same-named upstream is still there, one entry per branch — several
    upstream-tracking branches on one tip is rare enough that a submenu would be
    noise. It pushes --force-with-lease with a fully qualified refspec, so it
    works from any checkout rather than only when that branch is the one you are
    standing on: rewriting a branch you are not on and pushing it is one menu now,
    not a checkout in between.
  • The same warning everywhere — force push confirms through one sheet, and
    the toolbar's private confirmation dialog is gone. The button, the remote hub
    and the commit row ask the question in the same words, name the same branch,
    and warn in the same breath that the push aborts if the remote has commits you
    haven't fetched.
  • Open the worktree sitting on a commit — when another linked worktree is
    checked out at the commit under the cursor, Open Worktree <name> jumps
    to its tab. It is the only checkout in the menu that touches no git at all —
    the working tree already exists, on that commit — so it stays available while
    an operation is running, alongside the copy items. Offered for a worktree
    holding a branch and for one on a detached HEAD, and only while its directory
    is still on disk.
  • Worktrees live inside their project — a linked worktree used to open as
    though it were an unrelated repository: its own entry in recents, its own icon
    in the rail, no sign of what it belonged to. Now the recents entry records the
    repository, a worktree tab inserts next to its project's tab — a project
    opened later adopts the worktree tabs already there — and the rail draws it
    smaller and indented, with a branch glyph in the corner and a tooltip that
    says which project it is a worktree of. The relationship is read at open time
    from --git-common-dir and never stored, so a worktree removed behind the
    app's back leaves nothing stale behind, and a submodule or a bare repository
    is not mistaken for one.

Requirements

  • macOS 14 or later.
  • A git — whichever comes first on your login shell's PATH, else Apple's. With
    none installed at all, the Welcome screen says so once, with the command that
    fixes it.

Not here yet

  • A command palette.
  • Dragging a commit onto a branch. The rebase editor covers reordering a range;
    history by drag-and-drop is a separate decision, and it hasn't been made.

During the beta

Free, for any use. Licensing starts at 1.0: free for personal projects, paid per
seat for commercial use — see the EULA.

The app updates itself — each update is checked against a signature before it is
applied. Settings ▸ Updates decides how much of that happens on its own. Bug
reports and requests go to the issue tracker.

Fretwire 0.5.0

Choose a tag to compare

@olegklimakov olegklimakov released this 22 Aug 18:30

The fifth beta is about reading and about reach. The settings window stopped
being four tabs and became a list of small panes, which is what let three
preferences land in it that had nowhere to go before: how tall a history row is,
how large its text is beside everything else, and how loud the commit messages
are. Beside that, two commands grew past the one place they used to work — a
worktree can start at any commit now, and a squash can take a run from anywhere
inside the branch rather than only one ending at HEAD. And a branch pushed to
two remotes finally draws one pill instead of three that read the same.

New

  • Settings as a list of panes — six panes down the left instead of four
    tabs. A tab strip charges for each new preference twice, once in the strip and
    once in the pane it makes taller; Appearance alone had grown to carry five.
    Appearance keeps the theme and the text size, History takes the lane
    weight and the message emphasis with the sample that draws them both, and a
    new Diff pane takes the in-diff sidebar toggle together with the external
    diff and merge tools — which answer "what opens this file", not "which git
    runs", and were only ever under Git for want of a better home. The stored key
    is the old one, so an upgrade reopens on the pane it left off.
  • A history you can set the density of — ⌘, ▸ History: Row height
    (Compact / Regular / Comfortable) and a History text size. The history is
    the one list in the app with a height of its own — the refs sidebar and the
    file lists are as tall as what is in them — which is what makes "how many
    commits fit on screen" a question worth answering; Compact fits about a
    quarter more. The text size multiplies the app-wide one rather than replacing
    it, so ⌘+ and ⌘− still move both, and nobody has to choose between comfortable
    panels and a dense history. Everything inside a row follows it — message,
    author, date, SHA, ref pills, avatar — while the column header stays on the
    app-wide scale, being the table's chrome rather than its content.
  • Commit messages you can turn down — the subject is the brightest ink on
    the screen, and on a wide history that column of white pulls the eye off the
    lanes and the pills it is supposed to sit beside. Three steps, each an existing
    text rank rather than a new colour, so the message keeps its place in the
    hierarchy everything else is built from.
  • One pill per branch — a pushed branch used to decorate two pills printing
    the same word: past the column's label budget both truncate to the last
    segment, and the only difference left was an icon the eye has to hunt for. The
    refs sharing a branch name fold into one pill now — the local name, an icon per
    ref inside it — and the tooltip and the VoiceOver label spell out every full
    name, including which remotes carry it. Tags and the detached-HEAD marker keep
    their own pill: a tag named like a branch is a different thing pointing at the
    same commit.
  • A worktree that starts at a commitAdd Worktree Here… on any history
    row, beside Create Branch Here and Create Tag Here, which are the same "work
    from this point" aimed elsewhere. On a branch made for the occasion, because
    that is the only thing that can be checked out at an arbitrary commit — a
    directory sitting on a bare commit is a detached HEAD nobody asked for — with
    the folder seeded from the short hash until a branch name is typed.
  • Squash a run of commits — a selection of five could previously be folded
    only by opening the rebase editor and marking four rows by hand, and only if it
    ended at HEAD. Squash N Commits… now takes any contiguous run inside the
    branch: the base is the oldest selected commit's parent, everything above the
    run is replayed on top, and the messages are joined exactly as a squash into a
    parent already did — so the command is a confirmation, not a second editor. The
    menu entry reads the run off the selection without touching git, so it is a
    command or an explanation ("Squashing needs commits in a row", "Merge commits
    can't be squashed"), never a dead button.
  • Escape leaves the diff — reading a diff, the only way back to the history
    was the chevron in its header, a mouse trip for something every other Mac app
    answers with the key already under the reader's finger. It stands down wherever
    there is a caret: the search field and the commit message answer Escape
    themselves.

Fixed

  • Light back to System left the windows half-themed — the palette resolved
    to dark while every window went on drawing light chrome, which reads as broken
    colours and washed-out type. Light and Dark never showed it, because there the
    next forced value overwrites the last. The forcing went through SwiftUI's
    preferredColorScheme, which sets the window's appearance and does not unset
    it when the value goes back to nil. The appearance is the application's now, so
    unsetting it is an operation that exists — and nothing forced is what keeps the
    Mac's own setting readable, which is the signal the System choice follows.
  • A local branch under a prefix drew a remote's pillfeature/x is
    spelled exactly like a branch on a remote named "feature", and the graph read
    it as one, cloud icon and all. Decorations are read as full refnames now.
    Refs outside refs/heads, refs/remotes and refs/tags decorate nothing:
    a stash's internals and a fetched refs/pull/*/head used to draw a pill named
    after a path.

Requirements

  • macOS 14 or later.
  • A git — whichever comes first on your login shell's PATH, else Apple's. With
    none installed at all, the Welcome screen says so once, with the command that
    fixes it.

Not here yet

  • A command palette.
  • Dragging a commit onto a branch. The rebase editor covers reordering a range;
    history by drag-and-drop is a separate decision, and it hasn't been made.

During the beta

Free, for any use. Licensing starts at 1.0: free for personal projects, paid per
seat for commercial use — see the EULA.

The app updates itself — each update is checked against a signature before it is
applied. Settings ▸ Updates decides how much of that happens on its own. Bug
reports and requests go to the issue tracker.

Fretwire 0.4.0

Choose a tag to compare

@olegklimakov olegklimakov released this 21 Aug 15:25

The fourth beta closes the item the third one listed as not here yet: an
interactive rebase editor that takes a whole branch at once, rather than one
commit at a time. Beside it the app learned a light theme — the same design
solved for a light screen, not inverted — and the history pane got the work it
was owed: columns you can drag, lanes thin enough to stay out of the way of the
messages beside them, and a scroller that stays with the pane however far
sideways you have gone.

New

  • An interactive rebase editor — one sheet holding the range from a base to HEAD, in the order git will replay it, with pick / reword / squash / drop and reordering on every row. Three ways in: Rebase from Here… on a commit, Rebase N Unpushed Commits… on the current branch (its menu, and the toolbar's branch pill), and a selection that forms a run ending at HEAD. No editor window ever opens: reword is written as pick and squash as fixup, and every message this app decides on is applied by an exec git commit --amend line at the end of its group, so each resulting commit gets its own text. A plan that stops on a conflict stays put — Continue still works, because the files git's todo names are still where it left them.
  • A light theme — ⌘, ▸ Appearance ▸ Theme: System, Light, Dark. Every token keeps the hue and chroma of the dark token it replaces and moves only in lightness, until its contrast against the page matches what the dark theme already measures. Two places a mirror image would have been wrong: the lanes keep their lightness spread, so eight branches stay eight colours you can tell apart, and conflict becomes a terracotta — the system orange manages about 2.2:1 on a light ground, and an amber solved the usual way lands on top of the modified colour.
  • History columns you can drag — each fixed column now has a handle on the edge facing MESSAGE, a floor, a ceiling, and a width that persists across launches. MESSAGE stays elastic; it is whatever the others leave. And when the columns want more room than the pane has, the history scrolls sideways — header and rows together — instead of squeezing the message down to nothing and pushing the trailing columns off the edge.
  • Lanes that don't shoutGraph lines (Thin / Regular / Bold, thin now the default) in the history's gear popover and in ⌘, Appearance, which draws a live sample of each. The glow's width and opacity move with the core, so a thin lane isn't a thin line under a fat bloom, and the node rings keep their own width — a node is the commit itself. Hovering a row steps every lane that isn't its branch back to 30%. Lane turns are rounded elbows now, which look the same crossing one column as they do crossing ten.
  • A scroller that stays with the pane — the history's vertical indicator used to ride off the edge as soon as the columns were wider than the pane, so a vertical scroll gave no feedback at all. It is drawn outside the horizontal scroll now: at the pane's edge whatever the columns are doing, absent until something moves, lit under the pointer, draggable — and staying put under "Show scroll bars: Always", which it used to ignore.
  • A sidebar that steps out of a diff — a new preference in ⌘, Appearance, off by default: while a diff has the middle pane, the branch list folds away and hands it the room. The toolbar button still brings it back, and there it means "for this diff", not "from now on".

Requirements

  • macOS 14 or later.
  • A git — whichever comes first on your login shell's PATH, else Apple's. With none installed at all, the Welcome screen says so once, with the command that fixes it.

Not here yet

  • A command palette.
  • Dragging a commit onto a branch. The editor above covers reordering a range; history by drag-and-drop is a separate decision, and it hasn't been made.

During the beta

Free, for any use. Licensing starts at 1.0: free for personal projects, paid per seat for commercial use — see the EULA.

The app updates itself — each update is checked against a signature before it is applied. Settings ▸ Updates decides how much of that happens on its own. Bug reports and requests go to the issue tracker.

Fretwire 0.3.0

Choose a tag to compare

@olegklimakov olegklimakov released this 19 Aug 18:50

The third beta, and both of its features are about work that used to happen in a
terminal beside the app. A git worktree is now a section of the sidebar — one
you can add to, open as a tab, and remove from — and any file can be handed to
the diff or merge tool you already have set up, because Fretwire runs your
git difftool rather than reimplementing one. The DMG got a window drawn for it
along the way.

New

  • Worktrees — a WORKTREES section appears in the sidebar as soon as a repository has one. Each row carries the folder, the branch it holds (or detached at <sha>), and a lock or prunable marker; its menu is Open in New Tab · Reveal in Finder · Copy Path · Remove…, and the section header holds Add Worktree… and Prune Missing Worktrees. A worktree opens as a tab of its own, and removing one closes the tab that was showing it. The Add sheet takes an existing branch or creates a new one, and fills the folder name in as <repo>-<branch>.
  • A branch checked out somewhere else says where — a branch another worktree holds shows a folder marker, and its menu reads Checked out in ~/code/app-review with Open Worktree above it, rather than a Checkout that git was always going to refuse. Where a refusal does arrive — "is already used by worktree at …" — it comes with the same button instead of a dead end. So does the refusal to remove a worktree with uncommitted work, and a locked one's confirmation says out loud that the lock is what's being overridden.
  • Your own diff and merge tool — ⌘D on the diff pane, or Open in External Diff Tool in the staging and commit-detail menus, hands the file to git difftool; a conflicted file gets Resolve in External Merge Tool and git mergetool, which stages what it resolves. Both read diff.tool / merge.tool out of your own git config, so a tool already working in your terminal needs no setting up here. Settings ▸ Git names the config line being followed, lists the tools this Mac actually has, and can override the choice for the app alone. One caveat, written there too: the tool has to wait for the editor — code without --wait returns before git's temporary files can be read.
  • An installer window worth opening — the DMG opens on a fretboard, with the icon's own teal curve running out of the app and up into /Applications, and the mounted volume carries the app's icon rather than a generic disk.

Fixed

  • A folder whose name ends in a spacegit rev-parse --show-toplevel answers with a path plus git's own newline, and trimming whitespace took the last character of such a name with it. Only git's terminator comes off now.

Requirements

  • macOS 14 or later.
  • A git — whichever comes first on your login shell's PATH, else Apple's. With none installed at all, the Welcome screen says so once, with the command that fixes it.

Not here yet

  • An interactive rebase editor. One commit at a time can be reworded, squashed or dropped; reordering a range still belongs in the terminal.
  • A command palette.

During the beta

Free, for any use. Licensing starts at 1.0: free for personal projects, paid per seat for commercial use — see the EULA.

The app updates itself — each update is checked against a signature before it is applied. Settings ▸ Updates decides how much of that happens on its own. Bug reports and requests go to the issue tracker.

Fretwire 0.2.0

Choose a tag to compare

@olegklimakov olegklimakov released this 18 Aug 15:12

The second beta. Most of it is about reaching a remote from a Mac that is not
the one the app was built on: running the git you installed rather than the
one Apple ships, ssh remotes and the host keys they need, and failures that say
which failure they are. Plus a crash on a wedged pipe, the tabs you had open at
quit, and repository badges that use more than one letter.

New

  • Your git, and your PATH — a Mac app inherits launchd's environment, not the login shell's, so every command ran as /usr/bin/git with almost no PATH under it. The app now reads the login shell's PATH once per launch and runs the first git on it — or one named in Settings ▸ Git, else Apple's shim — which brings gh's credential helper, gpg for signed commits and a core.sshCommand along with it. Settings ▸ Git shows which git was chosen, its version, where it came from, and the whole search path.
  • SSH remotes — clone and publish over ssh rather than https. Both sheets show which transport they will write, preselected from whether this Mac has a key to offer and changeable in place, and Change URL… moves a remote that already exists. An ssh remote pushes with no token in its environment at all.
  • Host keys — a host this Mac had never spoken to failed with "Host key verification failed" and nothing to do about it, since ssh can only ask that question on a terminal. The failure card now offers to look: ssh-keyscan's fingerprints beside a link to the list the host publishes, and known_hosts appended to only once you say they match. A key that changed gets no such button, only the ssh-keygen -R command to copy — that is either a rekeyed server or someone in the middle, and the app cannot tell which.
  • A silent ssh agent is named as one — a push that went nowhere looked exactly like a slow one, and the timeout blamed the network. An operation that involves ssh and is still running after eight seconds asks the agent whether it answers at all; if it does not, the app says so, with a Stop and the command to see it for yourself.
  • Pushing a branch that has no upstream — creates it on the remote and records the upstream with it, so the toolbar's ahead/behind works and the next plain push lands. A one-off push to another remote publishes the branch there without quietly redirecting where it pulls from.
  • The tabs from last time — the repositories open at quit, and which one was in front, come back at launch. A restored tab is not a visit: it does not reshuffle the recents order, and a path that has since moved or been deleted is dropped instead of opening as an error tab.
  • Badges that tell repositories apart (#2) — the icon rail took the first letter of a name, so project-a, project-b and project-c all read "P". A badge now abbreviates the whole name, a letter from each of the first two words (project-a → PA, MyApp → MA). Where no rule can separate two names, it can be set by hand — letters and a colour, kept per repository, ahead of any icon found on disk.
  • Install with Homebrew (#1) — brew install --cask olegklimakov/fretwire/fretwire. Updates still arrive through the app.

Fixed

  • A wedged pipe no longer takes the app with it — when something held a child's output pipe open past the child itself — a lingering git-remote-https, an ssh ControlPersist master — the waiting thread was reclaimed by closing the descriptor under a read still in flight, and FileHandle answers that with an Objective-C exception no Swift catch can intercept. Output is read through DispatchIO now, where giving up on the rest is an ordinary cancel.
  • Remote failures say which failure they are — having no credentials at all was reported as "the remote rejected these credentials", which was both untrue and a dead end. Missing credentials, rejected credentials, a refused key, an unknown or changed host key and an unreachable host are now told apart, each naming the host git named, and a missing-credentials card offers to connect an account for it.
  • The detail column stays where it was put — opening a file from the commit-detail list re-divided the window, and the column collected a little more width with every file until it stood at its maximum.
  • "Use Default Icon" is offered to VoiceOver — the badge's context menu reaches VoiceOver as named actions, and the reset was missing from that list, so a custom badge could only be undone by reopening the sheet.

Requirements

  • macOS 14 or later.
  • A git — whichever comes first on your login shell's PATH, else Apple's. With none installed at all, the Welcome screen says so once, with the command that fixes it.

Not here yet

  • An interactive rebase editor. One commit at a time can be reworded, squashed or dropped; reordering a range still belongs in the terminal.
  • A command palette.

During the beta

Free, for any use. Licensing starts at 1.0: free for personal projects, paid per seat for commercial use — see the EULA.

The app updates itself — each update is checked against a signature before it is applied. Settings ▸ Updates decides how much of that happens on its own. Bug reports and requests go to the issue tracker.

Fretwire 0.1.0

Choose a tag to compare

@olegklimakov olegklimakov released this 08 Aug 15:04
075eb2f

The first beta of Fretwire — a native macOS Git client built around the commit graph, with staging, diffs, and the everyday branch and remote operations attached to it. Every read and write goes through Apple's git, so what the app does is what the terminal would have done.

In this build

  • Commit graph — swim-lane layout with ref badges, per-identity author colours, stashes shown where they were taken, and a marked boundary where the checked-out branch diverges from the default one.
  • Staging — stage and unstage by file or by hunk, amend, commit; the working tree sits as a row above HEAD whenever it is dirty.
  • Diffs — side-by-side or unified, syntax-highlighted, with image previews, binary placeholders, and per-file history.
  • Branches, remotes, tags, stashes — checkout, create, rename, delete, merge, rebase, cherry-pick (one commit or a selection), revert, reset, fetch/pull/push per remote, and publishing to GitHub or GitLab. Anything that moves a branch confirms first; force push is only ever --force-with-lease, scoped to one branch.
  • Rewriting history — reword a message, squash a commit into its parent, or drop one, from the commit's own menu. Each says plainly that ids change, and refuses rather than half-applying when the tree is dirty.
  • Conflicts — a stopped merge, rebase, cherry-pick, revert or git am is detected and shown with Abort and Continue, and conflicted files keep their diff.
  • Several repositories at once — an icon rail on the left; each tab keeps its own history, selection and load state.
  • Live refresh — commits made in the terminal appear in the graph without a manual reload and without blanking the view.
  • Adjustable text size — the whole type ramp scales from ⌘, ▸ Appearance, or with ⌘+ / ⌘− / ⌘0.

Requirements

  • macOS 14 or later.
  • Apple's command line tools, for /usr/bin/git. If they are missing, the app says so and names the fix.

Not here yet

  • An interactive rebase editor. One commit at a time can be reworded, squashed or dropped; reordering a range still belongs in the terminal.
  • A command palette.

During the beta

Free, for any use. Licensing starts at 1.0: free for personal projects, paid per seat for commercial use — see the EULA.

The app updates itself — each update is checked against a signature before it is applied. Settings ▸ Updates decides how much of that happens on its own. Bug reports and requests go to the issue tracker.