プログラミング
Show HN: Git-knife – スプレッドシートのようにコミットメッセージ、作成者、日付を編集
Show HN: Git-knife – edit commit messages, authors, and dates like a spreadsheet (github.com)
要約
Git-knifeは、コミットメッセージ、作成者、日付などのGit履歴メタデータをスプレッドシートのようなGUIで編集できるデスクトップアプリケーションです。既存のGUIツールが苦手とするコミット日付の編集や、一括検索・置換機能を提供し、git commit-treeを使用してコミットを再構築することで安全に履歴を書き換えます。プッシュ済みの履歴を編集する際の警告や、編集前のバックアップ機能も備えています。
全文翻訳
Show HN: Git-knife – スプレッドシートのようにコミットメッセージ、作成者、日付を編集
git-knife 🔪 Git履歴を整形する — 各コミットのメッセージ、作成者、日付をテーブルのように編集します。
コミットメタデータ(メッセージ、作成日、コミッター日、作成者名/メールアドレス)を直接編集するためのクリーンなデスクトップGUIです。既存のGUI(GitKraken、Sublime Merge、Fork、lazygit)は、メッセージや順序の変更はうまく行いますが、コミット日付は事実上変更不可能とみなし、コミッター日/作成者情報を任意のコミットに対して公開しません。そのメタデータを書き換えることができるツール(git-filter-repo、git rebase env tricks、git commit-tree)にはGUIがありません。git-knifeはそのギャップを埋めます。Gitを再実装するのではなく、システムGit CLIにシェルアウトし、各コミットの元のツリーを再利用してgit commit-treeでコミットを再構築するため、ファイルの内容が変更されていないことが証明されます。
比較方法
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 | ✅ | ✅ | ✅ | ✅ | ✅
凡例: ✅ ファーストクラス · ⚠️ 可能だが扱いにくい/限定的 · ◐ 日付またはターミナルUI · ❌ サポートされていない · 🚧 計画中。
洗練されたGUIはメッセージの書き換えや順序変更はうまく行いますが、コミット日付(特にコミッター日)は事実上変更不可能とみなし、作成者情報に対する一括正規表現パスを提供するものはありません。そのメタデータを書き換えることができるツールにはGUIがありません。git-knifeはそれらの交差点です。クリーンなGUIで、すべてのフィールドを安全に一括編集できます。
ステータス(MVP)
✅ リポジトリを開き、現在のブランチのコミットをリストする
✅ メッセージ/作成者名+メール/作成日/コミッター日/コミッター名+メールを編集する
✅ これらのテキストフィールド全体で一括検索と置換(リテラルまたは正規表現)(間違ったメールアドレスをすべて修正するのに最適)
✅ 適用前にすべての変更をプレビューする
✅ 各書き換えの前に自動バックアップ参照 + ワンクリック復元
✅ 書き換えが既にプッシュされた履歴に触れる場合に警告する
✅ マージコミットはロックされています(このバージョンでは編集不可)
⛔ まだ: 順序変更/squash/削除、マージ書き換え、ステージング/ブランチ/リモート
要件
Git (2.x)
Node.js + pnpm (corepack enable pnpm, or npm i -g pnpm)
Rust (stable) — https://rustup.rs からインストール
Tauri v2 の Linux システム依存関係: 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
最初のcargo buildはTauriクレートをダウンロードしてコンパイルします(数分かかります)。
バンドルのビルド
pnpm tauri build
パッケージング(tauri build)にはアプリアイコンが必要です。それらは既にsrc-tauri/icons/の下にコミットされています。任意の正方形のPNGからpnpm tauri icon path/to/icon.pngで再生成します。開発実行ではそれらは必要ありません。
自動リリース(GitHub Actions)
.github/workflows/release.yml は、tauri-actionを使用してmacOS、Linux、およびWindows用のネイティブインストーラーをビルドし、GitHubリリースドラフトに添付します。タグをプッシュしてリリースを作成します: git tag v0.1.0 git push origin v0.1.0(またはリポジトリのアクションタブから手動でトリガーします)。まだコード署名は設定されていないため、macOS/Windowsビルドは署名されていません — 初期テスターには問題ありません。
履歴の編集とプッシュ
コミットの編集
リポジトリを開きます(Browse…またはパスを貼り付けます)。非マージコミットをクリックしてエディタを展開します。メッセージ、作成者/コミッター名、メールアドレス、または日付を変更します。編集された行はハイライト表示されます。日付フィールドはコミットの元のUTCオフセットを保持します。Review & applyをクリックし、old → newのプレビューを確認して確認します。git-knifeはローカルブランチのみを書き換えます。リモートに接続したり、あなたのためにプッシュしたりすることはありません。プッシュは常にあなたの明示的なステップです。
一括検索と置換
コミットテーブルの上にあるBulk find & replaceをクリックして、一度に多くのコミット間でテキストを変更します。
- 対象とするフィールド(メッセージ、作成者/コミッター名、作成者/コミッターメール — 任意の組み合わせ)を選択します。
- Find / Replace を入力します。
- Regex を切り替えてパターンマッチング($1 バックリファレンス付き)を行うか、オフのままにしてリテラル検索を行います。大文字小文字を区別するはデフォルトでオンです。
- パネルは一致するコミットと置換の数をリアルタイムでカウントします。
- Stage edits をクリックしてハイライト表示された行に変換し、その後、通常どおり Review & apply します。
例 — すべてのコミットを古いメールアドレスから新しいメールアドレスに移動します: 作成者メール + コミッターメールを対象とし、old@example.com を検索して new@example.com に置換します。
マージコミットはスキップされ、 successive passes は合成されます。
書き換えのプッシュ
コミットの編集は、そのハッシュとそれ以降のすべてのコミットのハッシュを変更するため、ローカルブランチとリモートが分岐します。通常のgit pushは非ファストフォワードとして拒否されます。lease付きでプッシュします: git push --force-with-lease origin <branch> --force-with-lease は、リモートが最後のフェッチ以降に移動した場合、プッシュを拒否するため、チームメイトのコミットをサイレントに上書きすることを防ぎます。この安全チェックをスキップするプレーンな--forceよりもこちらを推奨します。
git-knifeは、編集が既にアップストリームに存在するコミットにまで及ぶ場合に、「rewrites pushed history」という警告を表示します。可能であれば、プッシュされていないコミットのみを編集してください。共有履歴の書き換えは、他のすべての人に再同期を強制します。
共有履歴を書き換えた後
既に古いコミットをプルした人は誰でも、分岐した履歴を持つことになります。彼らはそれぞれ、ローカルブランチを新しいリモート状態に再同期します:
git fetch origin
git reset --hard origin/<branch> # ローカル専用コミットを破棄します — まず調整してください
書き換えの元に戻す
アプリ内: Backups パネルは、ワンクリックで書き換え前のチップを復元します。
CLIから: 各適用はバックアップ参照を保存しました — git for-each-ref refs/knife-backup # 書き換え前のチップを見つける
git reset --hard <backup-ref-or-hash> # ブランチを元に戻す
git reflog にも古いチップがリストされます。既にforce-pushしている場合は、ローカルで復元してから再度 git push --force-with-lease します。
署名ノート(透過的)
デフォルトでは、git-knifeは各書き換えられたチップコミットに小さな、開示されたノートを独自のノート参照に添付します。これにより、通常のノートに触れることはありません。
git notes --ref=git-knife show <commit> # 読み取る
git for-each-ref refs/notes/git-knife # このリポジトリはgit-knifeによって編集されましたか?
通常のgit log(別参照)では見えませんが、完全に検出可能です — 隠されたエンコーディングはありません。アプリの 🔪 signature note チェックボックスでいつでもオフにできます(設定は記憶されます)。リポジトリから完全に削除するには:
git update-ref -d refs/notes/git-knife
仕組み
src-tauri/src/git.rs — gitを起動する唯一の場所。
commits.rs — open_repo, list_commits (NUL/レコードセパレーター解析)。
rewrite.rs — preview_edits + apply_edits: 最も古い編集されたコミットからチップまでを commit-tree を介して再構築し、バックアップ参照を保存して、古いチップに対する比較とスワップでブランチを移動します。
backup.rs — refs/knife-backup/* をリストし、git reset --hard を介して復元します。
書き換え戦略は、scratchpad/verify_engine.sh(正確な commit-tree フローを再現し、コンテンツ差分が空であることをアサートします)によってGitレベルで検証されます。
安全性
各適用は、何も触る前に古いチップを指す refs/knife-backup/<branch>/<epoch> を作成します。何も強制削除されません。復元は常にBackupsパネルから利用可能です。