- Facebook が作成した
hg absorb の git 向けポーティング版
hg absorb は、ここ数年のバージョン管理システムにおける最も優れたワークフロー改善のひとつと言える
- 作業ディレクトリに未コミットの変更があり、それが draft changeset の上にあるときに
hg absorb を実行すると、未コミットの修正が適切な draft ancestor changeset に自動的に吸収される
- コミットを作成したり、手動で history 修正ルールを作ったりせずに、
hg histedit + "roll" の作業を実行できる
- コマンドは変更された行を見て、その行を変更した changeset を見つけ、未コミットの変更を含むようにその changeset を修正する
- 競合なしで変更を作れない場合は、未コミットのまま残る
- このワークフローは、レビューのフィードバック適用のような作業に非常に有用。ファイル変更を行って
hg absorb を実行すれば、変更とコミットの対応付けが自動的に整理される。まるで魔法のような機能
git absorb の利用シナリオ
- 複数のコミットがある feature ブランチがある
- チームメンバーがブランチをレビューし、いくつかのバグを指摘する
- バグ修正はあるが、atomic commit を重視しているので、
fixes のような曖昧なコミットひとつにまとめたくない
git commit --fixup のためにコミット SHA を手動で探したり、手動で対話的 rebase を実行したりする代わりに、次を行う:
git add $FILES_YOU_FIXED
git absorb --and-rebase
git absorb は、どのコミットを安全に修正できるか、そして各 staged 変更がどのコミットに属するかを自動的に識別する
- その後、これらの変更に対する
fixup! コミットを作成する
--and-rebase フラグを使うと、これらの fixup コミットは対応するコミットに自動的に統合される
- 信頼できない場合は、出力を手動で確認してから、git 組み込みの autosquash 機能を使って feature ブランチに fixup を統合できる
インストール
- 最新のタグ付きリリースからアーティファクトをダウンロードしてインストール可能
- Windows、MacOS、Linux 向けのアーティファクトを提供
使い方
- 吸収させたい変更を
git add で追加
git absorb を実行
- 結果に満足したら
git rebase -i --autosquash を実行
- 満足できなければ
git reset --soft で前の状態に戻す
How it works (roughly)
git absorb は、2 つのパッチ P1 と P2 が可換かどうかを確認する
- デフォルトでは直近 10 件のコミットを対象にする
- インデックス内の各ハンクについて、そのハンクが最新コミットと可換かどうかを確認する
- 可換でないコミットが見つかったら、そのハンクを fixup コミットに変換する
Configuration
Stack size
- デフォルトでは直近 10 件のコミットを対象にする
- より多くのコミットを対象にするには、
.gitconfig に maxStack の値を設定
One fixup per fixable commit
- デフォルトでは、吸収可能な各ハンクごとに個別の fixup コミットを作成する
-F フラグを使うと、同じコミットに吸収されるすべてのハンクに対して 1 つの fixup コミットだけを作成できる
Auto-stage all changes if nothing staged
- デフォルトでは staged されたファイルのみを対象にする
- staged された変更がないときにすべての変更を自動で stage するには、
autoStageIfNothingStaged を設定
Fixup target always SHA
- デフォルトでは、fixup コミットメッセージは対象コミットの要約を参照する
- 常に対象の SHA を参照するように設定可能
TODO
- 強制フラグの実装
- リモートのデフォルトブランチ確認の実装
- 個別の安全チェックを無効化するための小さな強制フラグの追加
- すべてのエラー出力がユーザーにとって有用であることを保証
- 成功時により多くのログを出力
- さらに多くのテストを追加
- スタックと可換性の詳細を文書化
- さらに多くの可換ケースを追加
- すべてのハンクを同時にメモリへ読み込まないようにする実装
- 同時修正から保護するためのインデックスロックの実装
GN⁺ のまとめ
git absorb は Facebook の hg absorb から移植されたツールで、コミットを自動修正することで開発ワークフローを改善する
- レビューのフィードバック適用時に非常に有用で、手動でコミットを探したり修正したりする必要なく自動処理してくれる
- 類似機能を提供する別のツールとして
git-autofixup がある。コミットメッセージをもとに fixup コミットを自動生成するツール
- 利点は、コードレビューのフィードバック反映が容易になり、コミット履歴がよりきれいになること。欠点は、自動化に過度に依存すると予期しない結果が起こりうること
2件のコメント
Hacker Newsの意見
git absorbを使っている人たちは、このツールは非常に便利だと考えているgit absorbは自動的に正しいコミットを見つけてくれるgit commit --fixup用のエイリアスを使って満足しているgit absorbを使ってみたが、親コミットを誤って選ぶことが多かったgit --fixupとgit rebase --autosquashを使ったことはないが、有用そうに見えるgit-absorbはさらに一歩進んでいるようだコミットと履歴を書き換えることには懐疑的
magitを使うと簡単にfixupコミットを作れるgit commit --fixupとgit rebase --autosquashを知ったgit rebase -iはさまざまな要求を満たしてくれる超きれいなコミット履歴に執着するのは理解できない
直近10件のコミットから、衝突なしで修正可能なコミットを選ぶという発想が理解できない
fixup^をよく使うこのコメント、刺さりますね。fixup / autosquash を少し触ってみたんですが、気にしているのは自分だけなのかなと思って、ちょっと虚無感が来ました...