GitHub – TheRealYT/git-knife ยท GitHub

โœจ Explore this must-read post from Hacker News ๐Ÿ“–

๐Ÿ“‚ **Category**:

๐Ÿ“Œ **What Youโ€™ll Learn**:

Stab your git history into shape โ€” every commit’s message, author, and dates,
edited like a table.

A clean desktop GUI for editing git commit metadata directly โ€” message,
author date, committer date, author name/email
.

Existing GUIs (GitKraken, Sublime Merge, Fork, lazygit) reword and reorder well
but treat commit dates as effectively immutable and don’t expose committer
date / author identity for arbitrary commits. The tools that can rewrite that
metadata (git-filter-repo, git rebase env tricks, git commit-tree) have no
GUI. git-knife fills that gap.

It never reimplements git โ€” it shells out to the system git CLI and rebuilds
commits with git commit-tree, reusing each commit’s original tree so file
contents are provably never changed
.

Tool Clean GUI Reword msg Reorder / squash / drop Edit author date Edit committer date Edit author/email Bulk find & replace (regex)
git-knife โœ… โœ… ๐Ÿšง planned โœ… โœ… โœ… โœ…
GitKraken โœ… โœ… โœ… โš ๏ธ amend-only โŒ โš ๏ธ โŒ
Sublime Merge โœ… โœ… โœ… โŒ โŒ โš ๏ธ amend โŒ
Fork โœ… โœ… โœ… โŒ โŒ โš ๏ธ โŒ
SmartGit โœ… โœ… โœ… โš ๏ธ โŒ โœ… โŒ
git-cola โ— โœ… โœ… โœ… โŒ โœ… โŒ
lazygit (TUI) โ— TUI โœ… โœ… โŒ โŒ โš ๏ธ โŒ
git-filter-repo (CLI) โŒ โœ… via callback โœ… โœ… โœ… โœ…

Legend: โœ… first-class ยท โš ๏ธ possible but awkward/limited ยท โ— dated or terminal UI ยท โŒ not supported ยท ๐Ÿšง planned.

The polished GUIs reword and reorder well but treat commit dates โ€” especially
the committer date โ€” as effectively immutable, and none offer a bulk regex pass
over author identity. The tools that can rewrite that metadata have no GUI.
git-knife is the intersection: a clean GUI that edits every field, in bulk, safely.

  • โœ… Open a repo, list commits on the current branch
  • โœ… Edit message / author name+email / author date / committer date / committer name+email
  • โœ… Bulk find & replace across those text fields, literal or regex (great for fixing a wrong email everywhere)
  • โœ… Preview every change before applying
  • โœ… Automatic backup ref before each rewrite + one-click restore
  • โœ… Warns when a rewrite would touch already-pushed history
  • โœ… Merge commits are locked (not editable in this version)
  • โ›” Not yet: reorder / squash / drop, merge rewriting, staging/branches/remotes
  • git (2.x)
  • Node.js + pnpm (corepack enable pnpm, or npm i -g pnpm)
  • Rust (stable) โ€” install via https://rustup.rs
  • Linux system deps for Tauri v2: webkit2gtk-4.1, libgtk-3, libayatana-appindicator3, librsvg2
    (Debian/Ubuntu: sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev)
pnpm install
pnpm tauri dev

The first cargo build downloads and compiles the Tauri crates (a few minutes).

Packaging (tauri build) needs app icons. They’re already committed under
src-tauri/icons/; regenerate from any square PNG with
pnpm tauri icon path/to/icon.png. Dev runs don’t need them.

Automated releases (GitHub Actions)

.github/workflows/release.yml builds native installers for macOS, Linux, and
Windows
with tauri-action and
attaches them to a draft GitHub Release. Cut a release by pushing a tag:

git tag v0.1.0
git push origin v0.1.0

(or trigger it manually from the repo’s Actions tab). No code signing is set
up yet, so macOS/Windows builds are unsigned โ€” fine for early testers.

Editing history & pushing

  1. Open a repository (Browseโ€ฆ or paste the path).
  2. Click any non-merge commit to expand its editor.
  3. Change the message, author/committer name, email, or dates. Edited rows are
    highlighted; the date fields keep the commit’s original UTC offset.
  4. Click Review & apply, check the old โ†’ new preview, and confirm.

git-knife rewrites only your local branch. It never contacts a remote and
never pushes for you โ€” pushing is always your explicit step.

Click Bulk find & replace above the commit table to change text across many
commits at once:

  • Pick which fields to target (message, author/committer name, author/committer
    email โ€” any combination).
  • Enter Find / Replace. Toggle Regex for pattern matching with $1
    backreferences, or leave it off for a literal search. Case-sensitive is on
    by default.
  • The panel live-counts matching commits and replacements. Click Stage edits
    to turn them into highlighted rows, then Review & apply as usual.

Example โ€” move every commit from an old email to a new one: target Author
email
+ Committer email, find old@example.com, replace new@example.com.
Merge commits are skipped, and successive passes compose.

Editing a commit changes its hash and the hash of every commit after it, so
your local branch and the remote have diverged. A normal git push is rejected
as non-fast-forward. Push with a lease:

git push --force-with-lease origin <branch>

--force-with-lease refuses the push if the remote moved since your last fetch,
so you can’t silently clobber a teammate’s commits. Prefer it over plain
--force, which skips that safety check.

git-knife shows a “rewrites pushed history” warning when your edit reaches
into commits that already exist on the upstream. If you can, edit only unpushed
commits โ€” rewriting shared history forces everyone else to re-sync.

After rewriting shared history

Anyone who already pulled the old commits now has divergent history. Each of them
re-syncs their local branch to the new remote state:

git fetch origin
git reset --hard origin/<branch>   # discards local-only commits โ€” coordinate first
  • In-app: the Backups panel restores the pre-rewrite tip in one click.

  • From the CLI: every apply saved a backup ref โ€”

    git for-each-ref refs/knife-backup      # find the pre-rewrite tip
    git reset --hard <backup-ref-or-hash>   # move the branch back

    git reflog also lists the old tip. If you already force-pushed, restore
    locally and then git push --force-with-lease again.

Signature note (transparent)

By default git-knife attaches a small, disclosed note to each rewritten tip
commit, on its own notes ref so it never touches your regular notes:

git notes --ref=git-knife show <commit>   # read it
git for-each-ref refs/notes/git-knife      # was this repo edited by git-knife?

It’s invisible in a normal git log (separate ref) but fully discoverable โ€” no
hidden encoding. Toggle it off anytime with the ๐Ÿ”ช signature note checkbox in
the app (the setting is remembered). To strip it from a repo entirely:

git update-ref -d refs/notes/git-knife
  • src-tauri/src/git.rs โ€” the only place that spawns git.
  • commits.rs โ€” open_repo, list_commits (NUL/record-separator parsing).
  • rewrite.rs โ€” preview_edits + apply_edits: rebuilds the chain from the
    earliest edited commit to the tip via commit-tree, then saves a backup ref
    and moves the branch with a compare-and-swap on the old tip.
  • backup.rs โ€” lists refs/knife-backup/* and restores via git reset --hard.

The rewrite strategy is validated at the git level by
scratchpad/verify_engine.sh (reproduces the exact commit-tree flow and asserts
the content diff is empty).

Every apply creates refs/knife-backup// pointing at the old tip
before touching anything. Nothing is force-deleted; restore is always available
from the Backups panel.

๐Ÿ’ฌ **Whatโ€™s your take?**
Share your thoughts in the comments below!

#๏ธโƒฃ **#GitHub #TheRealYTgitknife #GitHub**

๐Ÿ•’ **Posted on**: 1786463653

๐ŸŒŸ **Want more?** Click here for more info! ๐ŸŒŸ

By

Leave a Reply

Your email address will not be published. Required fields are marked *