recommit について
recommitは、マージベース以降のコミットを一貫した目的ごとに組み直す、開発者向けのGit履歴編集スキルです。最終コミットツリーを保ち、復旧地点を記録します。
主な機能
- 01目的と変更ファイルごとのコミット計画
- 02マージベース以降のみを書き換え
- 03元のコミットツリーを維持
- 04計画したチェックを各コミットで実行
- 05復旧地点の記録
活用シーン
- 01雑多なコミットをレビュー可能な変更に分割
- 02依存関係が先になるようコミットを並べ替え
- 03再構築した各コミットを個別に検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ wkentaro/ agent-skills --skill recommitインストール後、Claude Code で/recommitを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
REBUILD.mdagents/openai.yamltests/workflow_test.sh詳細
Recommit
ブランチのマージベース以降のコミットを書き換え、各コミットが独立したストーリーとして完結する一連のコミットにします。最終的にコミットされたツリーは保持します。このスキルで変更するのは履歴であり、コードではありません。
動作を変更する場合、ターゲットブランチにすでに含まれているコミットを書き換える場合、または調整なしに他の人が作業のベースとしているブランチでは、このスキルを使用しないでください。
契約
- Git から見える作業ツリーがクリーンな状態で開始し、終了してください。
- 確認済みのマージベース以降のコミットのみを書き換えてください。
- 元のブランチ先端にあるコミット済みツリーを正確に保持してください。
- 書き換え前に、提案するコミット列と復旧ポイントを提示してください。
ワークフロー
0. 安全な範囲を特定する
ブランチ名が指定され、Git から見える作業ツリーがクリーンであることを必須条件とします。
git branch --show-current
git status --porcelain=v1 --untracked-files=all
ブランチ名が空の場合、またはステータスの出力が空でない場合は中止してください。クリーンな状態で開始すれば、記録したブランチ先端を完全な復旧ポイントにできます。レビュー修正がまだコミットされていないためにツリーが汚れている場合は、git commit --fixup=<sha>、またはインストール済みであればgit absorbを使うと、それらをこのスキルでまとめるfixup!コミットにできることをユーザーに伝えてください。
PR または MR のトラッカーメタデータが利用できる場合は、そこからターゲットを特定し、リモートが存在する場合はリモート追跡参照を更新してください。トラッカーメタデータがない場合は、origin/HEADを使用してください。これらの情報源が存在しない場合、または互いに一致しない場合にのみ、ユーザーに確認してください。
ターゲットを検証し、次の値を記録してください。
git rev-parse --verify <TARGET_REF>^{commit}
git rev-parse HEAD
git rev-parse HEAD^{tree}
git merge-base <TARGET_REF> HEAD
ターゲット参照をTARGET_REF、出力をORIG、ORIG_TREE、MERGE_BASEと呼びます。別々のツール呼び出しでも値が保持されるよう、後続のコマンドでは記録したリテラル値を使用してください。範囲の形状を確認してください(手順1では差分全体を読みます)。
git log <MERGE_BASE>..<ORIG> --oneline
git diff <MERGE_BASE>..<ORIG> --stat
ターゲットが判明し、範囲が空でなく、開始時の状態がクリーンで、記録した4つの値がすべて揃ったら、この手順は完了です。
1. コミット列を設計する
MERGE_BASE..<ORIG>の差分全体と既存のコミットを読みます。その後、提案するコミットを順番に記述してください。各コミットについて、タイトル、対象となるファイルまたはハンク、妥当性を確認するチェックを明示します。
- 各コミットには一貫した目的を持たせ、単独でビルドおよびテストできるようにしてください。
- 動作を変えない準備作業は、それを利用する変更より前に配置してください。変更を容易にするリファクタリングは先に反映します。
- 独立した改善には専用のコミットを割り当ててください。機能がなくても成立するバグ修正や UX 修正は、単独でレビューやリバートがしやすくなります。
- インフラストラクチャの変更は、最初にそれを使う変更とまとめてください。まだ何も呼び出していない仕組みを追加するコミットは、登場した時点ですでに不要なコードです。
- 依存関係は、それを利用するコミットより前に配置してください。
- 生成ファイル(ロックファイル、翻訳、スナップショット)は、それを必要とする変更とまとめてください。
- 分割するとどちらかのコミットが無効になる場合は、変更をまとめてください。いたずらに細分化するのも、寄せ集めのコミットと同じくらいよくありません。
変更されたすべてのパスとハンクが、提案したコミットのいずれか1つだけに割り当てられ、各コミットに検証コマンドまたは検証コマンドがない明確な理由が示されたら、この手順は完了です。
2. 計画を提示する
確認済みのターゲット、MERGE_BASE..<ORIG>、提案する完全なコミット列、復旧コマンドgit reset --hard <ORIG>を提示してください。書き換えによって変更されるのはローカルの履歴のみであり、このコマンド1つで元に戻せるため、返答を待たずに続行してください。
3. 履歴を再構築する
REBUILD.mdを読み、計画したコミット列に合う方法を使用してください。ローカルの履歴が計画したコミット列と一致し、最終的な変更がすべてコミットされたら、この手順は完了です。
4. 結果を確認する
Contract に記載されている状態の不変条件を確認します。
test "<ORIG_TREE>" = "$(git rev-parse HEAD^{tree})"
test -z "$(git status --porcelain=v1 --untracked-files=all)"
次に、REBUILD.md の一時ワークツリーの手順を使い、MERGE_BASE..HEAD の各コミットで予定されているチェックを実行します。後続のコミットによる変更が、先行するコミットのチェック中に見えてはいけません。
不変条件またはチェックに失敗した場合は、git reset --hard <ORIG> でクリーンな開始時点に戻し、ステータスがクリーンであることを確認して、失敗したチェックを報告します。復旧では記録済みの開始時点に戻すため、別途許可を得る必要はありません。
不変条件と、予定されているすべてのコミットごとのチェックに合格した場合にのみ、この手順は完了です。
5. 完了
git log <MERGE_BASE>..HEAD --reverse --oneline、保存した ORIG、および合格したチェックを提示します。
実例
「言語設定」PR には 2 つのコミットがありました。1 つ目は _create_combo のリファクタリングで、2 つ目は汎用ダイアログの自動サイズ調整の改善、note キャプション機構、および 20 個の生成済み翻訳ファイルを含む、さまざまな変更をまとめた feat コミットでした。予定されていた順序は次のとおりです。
refactor(settings): extract _create_comboに、動作を変えない準備作業をまとめます。feat(settings): fit the dialog height to the active tabに、累積的なハンクのステージングで分離した、単独で完結する UX の修正をまとめます。feat: add a Language settingに、この機能、note機構(ここまで使われていなかったもの)、および生成された翻訳をまとめます。
最終ツリーは ORIG_TREE と一致し、一時ワークツリーですべてのコミットが lint と型チェックに合格しました。