git-knife 🔪

git-knife is een schone desktop-GUI voor het direct bewerken van git commit-metadata: het bericht, de datum van de auteur, de datum van de committer, en de naam/e-mail van de auteur.

Bestaande GUI's (zoals GitKraken, Sublime Merge, Fork, lazygit) kunnen berichten goed herschrijven en commits herordenen, maar behandelen commit-datums effectief als onveranderlijk en geven de committer-datum of de identiteit van de auteur voor willekeurige commits niet vrij. Tools die deze metadata wel kunnen herschrijven (git-filter-repo, git rebase env-trucs, git commit-tree) hebben geen GUI. git-knife vult dit gat op.

De applicatie implementeert git niet opnieuw; het maakt gebruik van de systeem-git CLI en bouwt commits opnieuw op met git commit-tree. Hierbij wordt de oorspronkelijke 'tree' van elke commit hergebruikt, waardoor kan worden bewezen dat de inhoud van bestanden nooit verandert.

Vergelijking met andere tools

ToolSchone GUIBericht herschrijvenHerordenen / squash / dropAuteur-datum bewerkenCommitter-datum bewerkenAuteur/e-mail bewerkenBulk zoeken & vervangen (regex)
git-knife
🚧 gepland
GitKraken
⚠️ alleen amend⚠️
Sublime Merge
⚠️ amend
Fork
⚠️
SmartGit
⚠️
git-cola
lazygit (TUI)◐ TUI
⚠️
git-filter-repo (CLI)
via callback

Legenda: � eersteklas/volledig · ⚠️ mogelijk maar onhandig/beperkt · ◐ verouderde of terminal UI · ❌ niet ondersteund · 🚧 gepland.

De gepolijste GUI's kunnen berichten goed herschrijven en commits herordenen, maar behandelen commit-datums — vooral de committer-datum — als effectief onveranderlijk. Bovendien biedt geen van hen een bulk-regex pass over de identiteit van de auteur. De tools die deze metadata wel kunnen herschrijven, missen een GUI. git-knife is het snijvlak: een schone GUI die elk veld in bulk en veilig bewerkt.

Status (MVP)

Een repo openen, commits op de huidige branch oplijsten.

Bericht / auteursnaam+e-mail / auteur-datum / committer-datum / committer-naam+e-mail bewerken.

Bulk zoeken en vervangen in deze tekstvelden, letterlijk of via regex (ideaal voor het overal herstellen van een foutief e-mailadres).

Elke wijziging bekijken in een preview voordat deze wordt toegepast.

Automatische backup-ref vóór elke rewrite + herstel met één klik.

Waarschuwing wanneer een rewrite betrekking heeft op reeds gepushte geschiedenis.

Merge commits zijn vergrendeld (niet bewerkbaar in deze versie).

  • ⛔ Nog niet beschikbaar: herordenen / squash / drop, merge-herschrijven, staging/branches/remotes.

Systeemvereisten

  • git (2.x)
  • Node.js + pnpm (corepack enable pnpm, of npm i -g pnpm)
  • Rust (stable) — installeren via https://rustup.rs
  • Linux systeemafhankelijkheden voor 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)

Uitvoering en Build

Ontwikkelomgeving (Dev)

pnpm install
pnpm tauri dev

De eerste cargo build downloadt en compileert de Tauri crates (dit duurt enkele minuten).

Een bundle bouwen

pnpm tauri build

Packaging (tauri build) vereist app-icoontjes. Deze staan al in src-tauri/icons/; je kunt ze regenereren vanuit een vierkante PNG met: pnpm tauri icon path/to/icon.png. Dev runs hebben deze niet nodig.

Geautomatiseerde releases (GitHub Actions)

.github/workflows/release.yml bouwt native installers voor macOS, Linux en Windows met tauri-action en voegt deze toe aan een concept-release op GitHub. Maak een release door een tag te pushen:

git tag v0.1.0
git push origin v0.1.0

(Of trigger dit handmatig via het Actions-tabblad van de repo). Er is nog geen code signing ingesteld, dus macOS/Windows builds zijn onondertekend — dit is voldoende voor vroege testers.

Het bewerken van de geschiedenis en pushen

Een commit bewerken

  1. Open een repository (via Browse… of door het pad te plakken).
  2. Klik op een willekeurige non-merge commit om de editor uit te vouwen.
  3. Wijzig het bericht, de naam/e-mail van de auteur/committer, of de datums. Bewerkte rijen worden gemarkeerd; de datumvelden behouden de oorspronkelijke UTC-offset van de commit.
  4. Klik op Review & apply, controleer de preview (oud → nieuw) en bevestig.

git-knife herschrijft alleen je lokale branch. Het maakt nooit contact met een remote en pusht nooit voor jou — pushen is altijd een expliciete stap van de gebruiker.

Bulk zoeken en vervangen

Klik op Bulk find & replace boven de commit-tabel om tekst in veel commits tegelijk te wijzigen:

  1. Kies welke velden je wilt targeten (bericht, auteur/committer naam, auteur/committer e-mail — elke gewenste combinatie).
  2. Voer de zoekterm (Find) en vervanging (Replace) in. Schakel Regex in voor patroonmatching met $1 backreferences, of laat dit uit voor een letterlijke zoekopdracht. hoofdlettergevoeligheid staat standaard aan.
  3. Het paneel telt live het aantal overeenkomende commits en vervangingen. Klik op Stage edits om deze om te zetten in gemarkeerde rijen, en vervolgens op Review & apply.

Voorbeeld — verplaats elke commit van een oud e-mailadres naar een nieuw adres: target Auteur-e-mail + Committer-e-mail, zoek oud@example.com, vervang door nieuw@example.com.

Merge commits worden overgeslagen en opeenvolgende passes worden gecombineerd.

Een rewrite pushen

Het bewerken van een commit verandert de hash van die commit en de hash van elke daaropvolgende commit, waardoor je lokale branch en de remote uiteenlopen. Een normale git push wordt afgewezen als non-fast-forward. Push met een lease:

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

--force-with-lease weigert de push als de remote is gewijzigd sinds je laatste fetch, zodat je niet per ongeluk commits van teamgenoten overschrijft. Gebruik dit bij voorkeur boven --force, die deze veiligheidscontrole overslaat.

git-knife toont een waarschuwing "rewrites pushed history" wanneer je bewerkingen betrekking hebben op commits die al op de upstream bestaan. Indien mogelijk, bewerk alleen niet-gepushte commits — het herschrijven van gedeelde geschiedenis dwingt iedereen om opnieuw te synchroniseren.

Na het herschrijven van gedeelde historie

Iedereen die de oude commits al heeft gepulld, heeft nu een afwijkende geschiedenis. Zij moeten hun lokale branch synchroniseren met de nieuwe remote-status:

git fetch origin
git reset --hard origin/<branch>   # verwijdert lokale commits — overleg dit eerst

Een rewrite ongedaan maken

  • In de app: Het Backups-paneel herstelt de pre-rewrite tip met één klik.
  • Via de CLI: Elke apply-actie bewaart een backup-ref:

``bash git for-each-ref refs/knife-backup # vind de pre-rewrite tip git reset --hard <backup-ref-or-hash> # zet de branch terug ` git reflog toont ook de oude tip. Als je al hebt geforceerd gepusht, herstel dit dan eerst lokaal en voer vervolgens opnieuw git push --force-with-lease` uit.

Handtekening-notitie (transparantie)

Standaard voegt git-knife een kleine, openbare notitie toe aan elke herschreven tip-commit. Dit gebeurt op een eigen notes-ref zodat het je reguliere notes niet beïnvloedt:

git notes --ref=git-knife show <commit>   # lees de notitie
git for-each-ref refs/notes/git-knife      # is deze repo bewerkt door git-knife?

Dit is onzichtbaar in een normale git log (omdat het een aparte ref is), maar volledig traceerbaar — er is geen verborgen codering. Je kunt dit op elk moment uitschakelen met het 🔪 signature note selectievakje in de app. Om het volledig uit een repo te verwijderen:

git update-ref -d refs/notes/git-knife

Technische werking

  • src-tauri/src/git.rs — De enige plek waar git-processen worden gestart.
  • commits.rs — Bevat openrepo en listcommits (parsing via NUL/record-separator).
  • rewrite.rs — Bevat previewedits + applyedits: bouwt de keten vanaf de vroegste bewerkte commit tot aan de tip opnieuw op via commit-tree, slaat vervolgens een backup-ref op en verplaatst de branch via een compare-and-swap op de oude tip.
  • backup.rs — Lijst refs/knife-backup/* op en herstelt via git reset --hard.

De rewrite-strategie is gevalideerd op git-niveau door scratchpad/verify_engine.sh (reproduceert de exacte commit-tree flow en bevestigt dat het content diff leeg is).

Veiligheid

Elke apply-actie maakt een referentie aan in refs/knife-backup/<branch>/<epoch> die naar de oude tip wijst voordat er iets wordt aangepast. Er wordt niets geforceerd verwijderd; herstel is altijd mogelijk via het Backups-paneel.