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
| Tool | Schone GUI | Bericht herschrijven | Herordenen / squash / drop | Auteur-datum bewerken | Committer-datum bewerken | Auteur/e-mail bewerken | Bulk 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, ofnpm 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
- Open een repository (via Browse… of door het pad te plakken).
- Klik op een willekeurige non-merge commit om de editor uit te vouwen.
- 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.
- 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:
- Kies welke velden je wilt targeten (bericht, auteur/committer naam, auteur/committer e-mail — elke gewenste combinatie).
- Voer de zoekterm (Find) en vervanging (Replace) in. Schakel Regex in voor patroonmatching met
$1backreferences, of laat dit uit voor een letterlijke zoekopdracht. hoofdlettergevoeligheid staat standaard aan. - 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— Bevatopenrepoenlistcommits(parsing via NUL/record-separator).rewrite.rs— Bevatpreviewedits+applyedits: bouwt de keten vanaf de vroegste bewerkte commit tot aan de tip opnieuw op viacommit-tree, slaat vervolgens een backup-ref op en verplaatst de branch via een compare-and-swap op de oude tip.backup.rs— Lijstrefs/knife-backup/*op en herstelt viagit 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.
Groetjes,