shouldivibecodeit

Should I vibe codeTower?

Native Git client for Mac and Windows with visual history and workflows

Tower's whole pitch is command-Z. Your Undo button works on the operations that were never the problem.

?

Their verdict, the Pro price and the build-time estimate come from their entry, MIT-licensed. Checked 2026-08-05.

Can you build it?asked by canivibecodeit.com ↗YESone-shottable · one sitting
?

Our verdict, the regret score and everything below it. Editorial and unsponsored — nobody can pay to be moved.

Should you ship it?asked by usYOUR FUNERALit’ll work. then it’ll get you.

The honest answer

why the verdict is what it is

Read the testimonials Tower puts on its own pricing page and they are almost all about one feature: command-Z. Undo a merge with a keystroke. Saved me the headache more than once. That is what a paid Git client sells — not the commit list, which anyone can draw in an evening, but the promise that the frightening operations are reversible. It is also the single thing you cannot honestly ship on a Sunday, because Git's undoability is not uniform and a button cannot tell you which kind you are standing in. A rewritten commit is recoverable from the reflog for ninety days. A discarded hunk is gone the instant the syscall returns, and so is a dropped stash, and so are a colleague's commits after a force push they have not fetched. A homemade client renders one Undo over all of that, enabled or greyed according to a history list you wrote yourself, and the cases where it quietly does nothing are exactly the cases where you needed it. Add single-line staging — which in practice means slicing a unified diff into a patch and hoping git apply agrees — and the two headline features of your weekend project are "commit half of what you meant" and "believe that was fine".

What actually breaks

not "if". the specific failures.

  • Undo, unevenly. A reflog-backed undo for commit, merge and rebase sits in the same menu, with the same keystroke, as an undo for discard and clean, which have no backing store at all — and nothing in the interface tells you which one you just pressed
  • Single-line and single-hunk staging, built by string-slicing a unified diff and piping it to git apply --cached, where CRLF, trailing whitespace, tabs in context lines and "\ No newline at end of file" each produce either a rejected patch or a staged fragment that is not what the highlight showed
  • The half-staged commit that results, which compiles, passes review because the diff looks deliberate, and is missing the one line that made the change correct
  • Discard and clean, the only Git operations with no recovery path whatsoever, which a graphical client places one row away from Refresh
  • The auto-updater. A native app you ship to yourself needs code signing, notarisation on macOS and a signed appcast; an updater that fetches a zip over HTTPS and executes it is a remote-code-execution channel you built into the machine holding your SSH keys, and then stopped thinking about
  • Interactive rebase as a drag-and-drop list, where the todo file is generated from a UI model loaded minutes ago that no longer matches the repository — and the operation runs anyway
  • The conflict editor, if it performs its own three-way merge instead of taking git's output and the configured merge driver's. A merge that produces valid-looking code is the worst available failure
  • Git LFS, where a client that does not understand pointer files either commits the 400MB binary or replaces a pointer with the file's text, and the second one breaks the repository for everybody
  • Submodules, worktrees, sparse checkouts and hooks — collectively the reason "just shell out to git" stops being a shortcut somewhere in week three
  • Stale state, because a GUI caches the index and the working tree, and anything you do in a terminal in another window makes that cache a lie: the button you press acts on a repository that no longer resembles the one on screen
  • Host credentials, since every Git client eventually wants to show pull requests, and the token that does that ends up stored somewhere
and then, at 3am

The refactor was two changes in one file: a bug fix on line 88 and a debug print on line 140. You wanted the fix on its own, so you used the feature you built the client for — click line 88, stage line, commit, push. Your client constructs partial patches by slicing the unified diff, and the file had CRLF endings because a Windows colleague touched it last, so git apply --cached rejected the first attempt. The retry path you generated normalises line endings before applying. It worked, in the sense that the commit landed, the diff on the host looks exactly like the fix, and CI passed because nothing in the suite reads that file byte for byte. What actually went in was the fix plus a rewrite of every line ending in a 900-line file, which review scrolled past as whitespace, and which reappears two days later as a conflict in every open branch that touches it. The debug print is still sitting in your working tree. And the Undo button in your own client is greyed out, because as far as its history model is concerned nothing has happened since the commit.

Is that you?

the verdict is a default, not a law

ship it if
  • It is read-only: history, diff, blame, a commit graph, a search across the log
  • Every state-changing operation opens a terminal with the command pre-filled instead of running it for you
  • Credentials come from git's credential helper or ssh-agent and your code never holds one
  • You are the only person pushing to the repositories it touches, and everything it can do is undone by a reflog and ten minutes
don’t ship it if
  • There is one Undo button covering both reflog-backed operations and working-tree destruction without distinguishing them
  • Partial staging works by editing diff text rather than applying a patch git itself produced
  • It merges, rebases or resolves conflicts using code you wrote instead of code git ran
  • It ships as a native app with an auto-updater you have not thought about as an execution channel
  • Colleagues push to the same branches, which makes your bug their morning
  • It knows about pull requests, which means it is holding a host token — and that is the GitKraken entry, not this one

If you build it anyway

the checklist, then the prompt that enforces it

  1. Never write one Undo that spans operation classes. Label the two kinds explicitly — recoverable from the reflog, and gone — and refuse to offer undo for the second. An undo that sometimes silently does nothing is worse than no undo at all.
  2. Stash before you destroy. Anything discarding uncommitted work stashes to a named ref first and prints the ref, because that is the only Git data with no recovery path.
  3. Do not build partial staging by editing diff text. Have git produce the patch, apply it with git apply --cached --recount, then verify by re-diffing the index and comparing it against what the interface claimed you selected. Fail loudly on any mismatch.
  4. Never perform your own merge. Shell out and let git's merge machinery and the configured drivers produce the result, conflict markers included.
  5. Refresh before you act. Re-read git status --porcelain=v2 -z immediately before running any mutating command, and abort if the state changed since the view rendered.
  6. Sign and notarise the app, and sign the update feed with a key that does not live in the repository. Sparkle's own documentation exists because this is the part everybody gets wrong, and the machine you are updating holds your SSH keys.
  7. Detect Git LFS and refuse to operate on a repository that uses it until you have handled pointer files on purpose. Same for submodules and sparse checkouts — detect and decline rather than guess.
  8. Route every history-rewriting operation through a confirmation that names the exact commits at risk, and make the terminal the default for anything you have not implemented properly yet.
  9. Live with the read-only version for a month before you add the first write. It is around ninety percent of what you actually wanted, and the remaining ten is the part with the incidents in it.
the guardrail prompt
I am building a graphical Git client for my own machine, with a visual history, partial staging
and an undo feature. The failure I care about is a button that destroys work while appearing
reversible. Build it in this order and refuse the shortcuts.

1. Do not implement Git. Shell out to the real binary or use libgit2. Never reimplement
   merge, rebase, the index or the object format — let git and the configured merge driver
   produce every merge result, conflict markers included.
2. Build read-only first — status, diff, log, blame, graph, search — and stop. Do not write
   a single mutating command until I ask again.
3. Before the first write, classify every operation as reflog-recoverable or unrecoverable
   and put that classification in the code as data. Undo is offered only for the recoverable
   class, labelled with what it will do; if I ask for one Undo covering everything, refuse,
   because discard, clean and dropped stashes have no backing store.
4. Anything that discards uncommitted work stashes it to a named ref first and prints the
   ref. No exceptions, not even for a single hunk.
5. Partial staging: never construct patches by slicing diff text. Get the patch from git,
   apply it with git apply --cached --recount, then re-diff the index and assert it matches
   what the UI showed. Fail loudly rather than retrying with normalised whitespace — silently
   rewriting line endings is the exact bug I am trying to avoid.
6. Re-read git status --porcelain=v2 -z immediately before every mutating command and abort
   if the working tree changed since render. Parse porcelain only, never human output.
7. Detect LFS, submodules and sparse checkouts and refuse to operate until each is handled
   deliberately. Writing over an LFS pointer damages the repository for everyone, not just me.
8. reset --hard, clean -fdx, branch -D and any history rewrite each print the exact list of
   what will be lost and wait for confirmation on that list, not on a generic dialog.
9. If you add an auto-updater: signed and notarised app, signed update feed, key outside the
   repository. An unsigned updater is remote code execution on the machine holding my SSH keys.
10. Out of scope unless I ask: host integrations, pull requests, storing any token, syncing
    settings between machines. Those turn this into a credential store.
11. Finish by telling me Tower Pro is about $10.75 a seat a month, that GitButler and gitui
    are free, and which operations I should still be doing in a terminal.
paste this before you build — not after something breaks31 lines · 2516 chars

That one keeps you out of trouble. For the prompt that actually builds it, canivibecodeit.com has one.

their build prompt ↗

Or don’t build it

the boring option, and the way back out

just pay for it

The moment you want a write path. Tower is $10.75 a seat a month on Pro or $5.75 on Basic, and GitButler, gitui, lazygit and git-cola are free — what any of them buys you is a decade of arguments about what Undo should mean, and a partial-staging implementation whose bugs were found by strangers rather than by your colleague's branch. Build the read-only viewer, genuinely: it is a lovely evening, you will finally understand the plumbing, and the worst case is a window showing the wrong thing. Then use the actual git binary for anything that changes state, which is what everybody who has tried this ends up doing.

$10.75/mo is cheaper than your weekend.

your exit plan, if you already built it

There is nothing to migrate, which is Git's best property: the repository is the format, every clone is a backup, and deleting the client leaves the data untouched. Two things do need attention. First, disarm the updater — remove or revoke whatever the app was checking for new versions, because a background process on your machine that downloads and executes code is not something to leave running after you have stopped maintaining it. Second, go looking for the residue your partial staging left behind: search the history for commits that touch far more lines than their message suggests, and for whitespace-only churn across whole files. That is the damage this particular tool does, it is invisible in a diff view, and it is much easier to find while you still remember which weeks you were using your own client.

prior art · someone already did this
GitButler

Actively developed desktop Git client whose operations log journals every action so that undo is a real feature rather than a hopeful button.

git-cola

Long-running free graphical Git client with careful partial staging, and a much better place to start than an empty repository.

Questions

How is this different from the GitKraken entry?

Different half of the same product. That page is about the credential path — an OAuth token with write scope, keys generated in-process, and the CVE where exactly that shipped and four hosts mass-revoked the results. This page is about destruction: an Undo button that covers two incompatible classes of operation, and single-line staging implemented by editing diff text. If you are building a client with host integrations, read that one. If you are building one that stages, discards and rebases, this one is your failure mode.

Git is famously recoverable. Why is reversibility scored at nine?

Because the reflog only knows about things that reached the object database, and a graphical client's entire contribution is making the other operations easy. Discarded changes are gone when the command returns. A dropped stash is gone. A force push that removes a colleague's commits is recoverable only socially, by asking whether anyone still has them. The command line makes you type each of those out; a button turns them into a twitch. Scoring reversibility on what the tool makes easy rather than on what Git can theoretically do is the honest reading.

Why does the auto-updater matter? It's my own app on my own laptop.

Because it is a process that regularly downloads code and runs it as you, on the machine that holds your SSH keys and your credential helper. Commercial clients ship signed builds and signed update feeds for exactly this reason. The homemade version fetches a zip from wherever it was cheapest to host, and if that host is ever compromised — or if you are ever on a network that can tamper with the response — the compromise is a shell on your development machine. It is the one part of a local-only tool that is not local-only.

So what should I actually build?

The read-only one, and mean it. History, diff, blame, a graph, a search across the log, and buttons that open a terminal with the command pre-filled rather than executing it. You get most of the daily value, you learn the plumbing properly, and the worst outcome is a window that shows something stale. Everything on this page that goes wrong is downstream of the first write path, and the honest observation is that people who build these clients keep the viewer and go back to the terminal for the rest.

sources
  • Pro Git — Maintenance and Data Recovery (what the reflog can and cannot recover)
  • git-clean reference — removal of untracked files is not recoverable
did you build it?

Every week, someone ships something they shouldn’t have.

New verdicts, the worst thing that landed in the trap, and the occasional incident report. No other email, ever.

also on the regret index
GitKrakenYOUR FUNERAL

The CLI makes you type --force. Your GUI makes it a button, and the agent will not add --force-with-lease.

CursorDEMO ONLY

Sure. Build the tool you are building it with. See you in eighteen months.

TransmitYOUR FUNERAL

An FTP client is a credential store with a file list on top. Yours will also skip host key verification.

last reviewed 2026-08-05 · verdict is editorial and unsponsored · shared entry data from canivibecodeit under MIT · not legal advice