Show HN: Git-knife —— 像操作表格一样编辑 Git 提交信息、作者和日期
Show HN: Git-knife – Edit commit messages, authors, and dates like a spreadsheet

原始链接: https://github.com/TheRealYT/git-knife

**git-knife** 是一款桌面图形界面工具,旨在填补 Git 生态系统中的一个主要空白:轻松且安全地编辑提交元数据。虽然 GitKraken 或 Sublime Merge 等现有工具在重写或重排提交方面表现出色,但它们将提交日期和作者身份视为不可变数据,且缺乏批量编辑功能。 **git-knife** 允许你: * **编辑任何元数据:** 修改提交信息、作者/提交者姓名和邮箱,以及作者和提交者的日期。 * **批量操作:** 在多个字段中执行查找和替换操作(支持正则表达式),例如更新整个项目历史记录中的旧邮箱地址。 * **安全第一:** 该应用程序在应用更改前提供清晰的预览,自动创建备份引用以实现一键恢复,并在你修改已推送到远程仓库的历史记录前发出警告。 在底层实现上,它使用系统命令行和 `git commit-tree` 来重建提交,确保文件内容保持不变。它专为需要清理混乱提交历史的开发者设计,省去了使用复杂命令行工具的烦恼,也打破了标准图形界面工具的局限性。

**Git-knife** 是一款新工具,允许开发者通过类似电子表格的界面编辑 Git 提交信息、作者和日期。它作为一款 Tauri 应用构建,支持用户通过正则表达式查找和替换来进行批量更新(例如更正作者邮箱或调整时间戳),且不会更改文件内容。 该项目在 Hacker News 上引发了关于其效用及软件开发现状的热烈讨论。尽管一些用户认为该工具是不必要的或“偷懒”的表现,但另一些用户则强调了其实际用例,例如更正仓库历史记录、统一团队贡献的元数据或管理历史归档。 辩论的很大一部分集中在大型语言模型(LLM)在编程中的作用上。批评者认为,现代开发者过于依赖人工智能生成的“样板代码”和冗长且模糊意图的注释。相反,支持者则认为 LLM 促成了此类小众且能节省时间的实用工具的诞生,否则这些工具可能永远不会出现。 在技术层面,该工具因其安全性而受到称赞:它通过调用 Git 命令行接口(CLI)运行,复用原始树对象以确保文件完整性,并在应用更改前创建备份分支。针对社区关于安全最佳实践的反馈,作者还增加了对签名提交的支持。
相关文章

原文

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 [email protected], replace [email protected]. 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/<branch>/<epoch> pointing at the old tip before touching anything. Nothing is force-deleted; restore is always available from the Backups panel.

联系我们 contact @ memedata.com