Git history you can
actually read.

A desktop client built around one idea: lanes that never move. Branches stay in their column so the shape of your history holds still while you read it.

1,052 commits read in 683 ms
lane layout solved in 1 ms
Switchyard C:\code\switchyard
main 4 lanes · painted to canvas, not the DOM
1,052commits, 683 ms to read
1 msto solve the lane layout
150,000commits, and the graph still scrolls smoothly
0bytes of your code sent anywhere

The tour

Four things you do all day.

Switchyard C:\code\switchyard
Fetch 2 Pull ↓2 Push ↑1 Stash Transfer feature/checkout-v2
Historyall refs, topological1,052
Commit3 changed objects
a4f19c2

Stop the total at the last filled row

Pennywise App Studio <pennywise.appstudio@gmail.com>
parent 7b02e1d · 18 Sep 2026

Changed objects
src/lib/totals.ts,
src/lib/table.ts,
src/lib/totals.spec.ts

Right click any commit to copy its file list. Select several and you get the distinct union, one file per line, comma separated.

  • Msrc/lib/totals.ts+42 -9
  • Msrc/lib/table.ts+18 -4
  • Asrc/lib/totals.spec.ts+120
  • Msrc/app/table/table.ts+7 -7
  • Dsrc/app/legacy-row.ts-64
Pennywise App Studio · signing on
FromC:\code\switchyard
ToC:\code\switchyard-release
  • invoice.model.tsresolving
  • invoice-api.service.tsresolving
  • invoice-list.component.tsresolving
  • invoice.spec.tsresolving
  • legacy-total.util.tsresolving
Nothing written yet

Chapter one

Read the history.

One commit per row, and a branch that keeps its column from its first commit to its last. Right click to copy the files a commit touched, or select a range and copy the distinct union.

Chapter two

Stage and commit.

Tick the files, write the message, commit. Your hooks run and your signing key is used, because every write spawns the real git binary rather than reimplementing it.

Chapter three

Read the diff.

Merges compare against the first parent, so lines are not shifted by a column the way a combined diff shifts them. Untracked files get a preview too.

Chapter four

Move files between repositories.

Paste the names, pick a source and a destination, and every entry is resolved and classified before a single byte is written. Nothing is guessed.

Straight lanes

A branch keeps its column.

Most clients let lanes drift sideways as you scroll, so the picture changes while you are reading it. Switchyard assigns lanes across the whole walk in topological order, so a branch holds its position from the first commit to the last.

Published surveys of commit graph drawing put one commit per row and straight branches in tension: almost no client does both. Switchyard does, because the layout is solved once, outside the renderer.

  • One commit per row, merges drawn as hollow nodes
  • Canvas sized to the window, so a 100,000 commit repository costs the same per frame as one with fifty
  • Lanes reserved and released in a single pass, so the first parent inherits its child's column
  • Text measurements cached, repaints coalesced into one frame
Drawn in your browser by a port of the app's own lane solver. Scroll back up and it redraws.

Everything you do in a day, without the terminal.

No feature here is a wrapper that reimplements git. Each one shells out to the binary already on your PATH, with arguments passed as an array so nothing is ever handed to a shell to reinterpret.

Stage, commit, amend, undo

Stage and unstage a file, a folder, a hunk or single lines, or everything at once. Amend the last commit, or undo it and keep the changes. Discarding always asks first and keeps a copy, so Undo puts the file back exactly as it was.

CtrlEntercommit

Fetch, pull, push

Ahead and behind counts sit on the button, with how long ago you last fetched, and it fetches by itself every 15 minutes. Progress shows as git works, and a download can be stopped. Force push uses a lease, never a bare force, so you cannot overwrite a colleague's work by accident.

Search the whole history

Filter by subject, author or sha as you type, or search all of history: path: for the commits that touched a file or folder, text: for the ones that added or removed some text.

Branches and stashes

Create, switch, rename, track and delete branches, here or on the remote, from a right click. Switching with changes asks whether to bring them or leave them on the branch for later. Stash, pop and drop without remembering which verb git wants.

Copy changed objects

Right click a commit for its file list. Select several commits and get the distinct union, one file per line and comma separated, ready to paste into a release note or a ticket.

Merge conflicts, one at a time

Conflicted files get a list of their own, each saying what kind of conflict it is. Click one to see the file with each conflict laid out as current and incoming, and take one side, the other, or both, conflict by conflict, or open the three pane merge editor. Every choice can be undone.

Pull requests

On GitHub, GitLab and Azure DevOps, self-hosted servers included: list, create, comment on, approve, check out and merge them, with a token of your own that is sent only to your service.

Undo

Commits, amends, merges, pulls, cherry-picks, resets and discards can be taken back from the message that follows, or with Ctrl+Z. Nothing already pushed is ever undone.

A file's history and blame

Right click any file for its history, followed through renames, or its blame, where each line leads to the commit that last changed it.

See what really changed

The words that changed are marked inside a changed line, code is coloured by its language, and a changed picture is shown before and after, side by side.

Compare any two commits

Pick two rows and see the combined file list with per-file status, without writing a range expression. Where a file changed on both sides you are asked whether to review the diff first or copy straight through.

Light and dark

Follows the system, or pin it. The canvas re-reads its palette on both routes, so the graph never paints one theme's ink on the other's ground.

Free for 30 days. Then one plan.

Every feature from the first day. The trial starts the first time you open the app.

  • No card, no account for the trial.
  • Cancel any time. It runs to the end of the period you paid for.
  • Never locked out. If a plan ends, the app goes read-only.
  • One licence, one computer. Moving it takes a click.

Payments by Dodo Payments, who send the receipt and your licence key. How it works · Refunds

Monthly

₹149 / month

or $2.99 a month outside India

  • Every feature, and updates as they ship
  • Billed monthly, after your free trial
Two months free

Yearly

₹1,490 / year

or $29.99 a year outside India

  • Everything in monthly
  • Billed once a year, after your free trial

Hands stay on the keyboard.

The ones you reach for most. Everything else is a few letters away in the command palette. None of them need a modifier you cannot reach with one hand.

CommitCtrlEnter
Every commandCtrlShiftP
Undo the last actionCtrlZ
Search historyCtrlF
Open a repositoryCtrlO
Clone a repositoryCtrlShiftO
RefreshCtrlR
Open in your editorCtrlShiftA
Next conflictF7
Close a dialogEsc

Move files between repositories.

Paste a list of file names, pick a source and a destination, and Switchyard works out what is new, what already exists, and what is identical before it writes anything.

src/lib/invoice.model.ts,
src/lib/invoice-api.service.ts,
src/lib/invoice-list.component.ts

Full paths, trailing commas, quotes and Windows backslashes all get normalised. A bare file name matching two files in the source is reported as ambiguous, never guessed. A path that would escape the destination root is refused.

  • NewNot in the destination yet.
  • Already existsDifferent contents. Review the diff or overwrite.
  • IdenticalSkipped, nothing to do.
  • Not foundReported so the list can be fixed.

Under the hood

Four decisions that shaped it.

01

It spawns real git

Every read and every write runs the git binary on your PATH, with arguments as an array rather than a shell string. So hooks fire, credential helpers work, commits get signed, and a .gitattributes filter behaves exactly as it does in your terminal.

02

The layout is solved, not drawn

Lanes are assigned in one topological pass over a reserved-lane array. A commit releases its own lane before reserving its parents, which is what lets the first parent inherit the column and keeps the branch straight.

03

The canvas is window sized

Painting covers the viewport, not the history, so per-frame cost is constant. The backing store is scaled to whole pixels rather than a fractional device ratio, which is what stops text going soft at 125 percent display scaling.

04

The window is sealed

Context isolation on, node integration off, and a narrow bridge of named calls instead of a general channel. The page is served over a private scheme rather than file://, so module loading works without relaxing web security.

What it is, and what it is not.

Worth reading before you download it, so nothing here surprises you later.

✓What it is

  • A fast reader of history, built for repositories where the branch shape matters
  • A daily driver for staging down to single lines, committing, branching, merging, resolving conflicts, stashing and syncing
  • A tool for lifting a named set of files from one repository into another, safely
  • Free for 30 days with every feature, then one simple plan — no account and no seat count
  • Checked by automated tests on every build, most of them driving real throwaway repositories and a real window

×What it is not

  • Not a git of its own. It runs the git on your PATH, so Git for Windows comes first
  • Not signed with a code signing certificate, so Windows will warn on first run
  • Not a replacement for your hosting service's website. Pull requests work with a token of your own; issues and pipelines stay in the browser
  • Not built for macOS or Linux yet, though nothing in it is Windows specific

Roadmap

What is built, and what is wanted.

Shipped

The graph, the diff, and the whole write path

Lane solving, canvas painting, staging, committing, amending, undo, revert, discard, branches, stashes, fetch, pull, push with a lease, history search, light and dark themes.

Since the first release
Shipped

Cross repository transfer

Paste a file list, resolve every entry against the source, classify it, review the diff where it matters, then write. Refuses any path that would escape the destination root.

Since the first release
Shipped

Merge conflict resolution

A banner names the operation that stopped and how many files are left, and conflicted files get a list of their own. Take the current or incoming side for a whole file, settle each conflict in the file or in a three pane merge editor, then continue or abort. Every choice can be undone.

In 0.1.10, reworked in 0.1.20
Shipped

Hunk and line level staging

Stage or unstage one hunk, or pick single lines in a diff. The hunk is found again in a fresh diff before anything is applied, so a file that changed since is refused rather than guessed at.

In 0.1.10
Shipped

Interactive rebase and cherry pick

Reorder, reword, squash, fix up or drop commits in one dialog, written as a rebase todo so git does the work, and cherry pick commits onto your branch.

In 0.1.10
Shipped

Pull requests and undo

See, create, comment on, approve, check out and merge pull requests on GitHub, GitLab and Azure DevOps. Take back a commit, a merge, a pull, a rewrite or a discard from the message that follows it. A file's history and blame, identities per folder or remote, and team settings for a repository.

In 0.1.12
Shipped

Sync that shows its work

Fetch, pull and push show their progress and can be stopped while that is safe. A remote that wants a password or a passphrase asks in the window, and the repository on screen is fetched every 15 minutes so the counts stay true.

In 0.1.13 and 0.1.14
Wanted

Signed installers, macOS and Linux

Windows warns on first run because the installer is not code signed, and signing needs a certificate that costs money every year. Updates are already checked against each release's fingerprint; a signature would let Windows vouch for them too.

Not yet funded

Questions

The things people ask first.

What does it cost?

Every copy starts with a 30-day free trial of everything, with no account and no card. After that it is ₹149 a month in India or $2.99 elsewhere, or yearly for two months less. There is one plan, and nothing in the app is held back from it. See pricing.

If a plan ends, the app does not lock you out: it goes read-only, so every repository can still be read, and writes come back the moment it is renewed.

Does it bundle its own git?

No. It uses the git already on your PATH. That is deliberate: your version, your config, your hooks, your credential helper and your signing key all keep working, and the app cannot drift out of step with the git you use in the terminal.

If git is missing the app says so plainly instead of failing halfway through an operation.

Will it ever rewrite my history without asking?

No. Every destructive operation sits behind a confirmation that names what will be lost. Force push uses --force-with-lease, so a push that would discard someone else's commits fails instead of succeeding.

How fast is it on a large repository?

Reading 1,052 commits from a real monorepo takes 683 ms, almost all of it waiting on git itself. Solving the lane layout for those commits takes about 1 ms.

Painting cost does not scale with history at all, because the canvas is sized to the window rather than to the number of rows.

Windows says the publisher is unknown. Is that expected?

Yes. Code signing needs a certificate that costs money every year, and there is no certificate yet. The warning is Windows telling you the truth: the binary is unsigned.

Does it auto update itself?

Yes, from version 0.1.10. It checks shortly after it starts and every few hours, downloads a new version in the background and checks it against the release's fingerprint. It installs when you press Restart to update, or the next time you quit. The banner offering an update the developer has marked as required cannot be dismissed. The release notes say what changed in each version.

Separately from updates, the developer has a safety switch that can make a faulty version read-only or stop it, so a release that goes wrong cannot keep doing damage while a fix is on its way. The next question says how it works.

What does the app send, and what does it check?

Nothing about your code: no repository paths, file names, branch names, email address or machine name. To count installs, it sends a random id it made up the first time it ran, with its version and platform. To know your trial and your plan, it sends a one-way hash of your computer's id, and your licence key when you paste one. The privacy policy lists all of it.

It regularly reads a status file for notices, updates, and a safety switch the developer can use to make a faulty version read-only or stop it. The app obeys the switch only when it is signed with one of the developer's keys: one never leaves the developer's own machine, and one is held by the website, which uses it only for the developer, after they confirm with a fresh code sent to their email. A switch lasts only for a set time, a year at most, and it never touches your repositories or files.

What happens to the graph while a fetch is running?

Nothing jumps. The repository is watched for changes with a debounce, and a refresh re-solves the layout from scratch rather than appending rows, so the shape you are looking at stays consistent with the history behind it.

Is any of this derived from another Git client's source?

No. Switchyard was written from scratch. Published documentation and algorithm write-ups were read; no other client's source code was. Where a project inspired an idea, the idea was reimplemented rather than copied.

Start your 30-day free trial

One installer for Windows. Every feature for 30 days, with no account and no card.

Checking for the latest release…

Try it free

Windows 10 and 11. Requires git on your PATH. The installer is not code signed, so Windows will ask you to confirm on first run.

30 days free, then ₹149 or $2.99 a month No telemetry on your code Updates install on your next restart