Git 2.54 and 2.55: 実験的な `git history` コマンドの探索
Git 2.54 and 2.55: 実験的な git history コマンドの探索
Git 2.54 および 2.55 のリリースで導入された git history コマンドは、git rebase -i の手動による複雑さを伴わずに、古いコミットを修正するための合理化されたアトミックな方法を提供します。子孫ブランチのリベースを自動化することで、Jujutsu (jj) のような代替のバージョン管理システムに見られるいくつかの高度な履歴管理機能を、Git のコア配布物に直接もたらします。
git history によるアトミックな履歴修正
git history はアトミックであるように設計されています。つまり、完全に成功するか、あるいは何も行わないかのどちらかです。ワーキングツリーを壊れた状態や競合状態に残すことを防ぐため、このコマンドはマージコンフリクトが発生する操作を拒否します。これは、手動でのコンフリクト解消のために一時停止する標準的なインタラクティブ・リベースとは大きく異なります。
git history fixup
git history fixup <commit> を使用すると、ステージングされた変更を以前のコミットに統合(fold)できます。これは git commit --fixup と autosquash リベースの組み合わせに似て動作しますが、ブランチ更新の範囲が拡張されています。
git rebase --update-refs はアクティブなリベース範囲内の参照のみを移動しますが、git history fixup は対象のコミットから派生したすべてのローカルブランチを特定し、書き換えます。これにより、関連するすべてのフィーチャーブランチが修正と同期された状態に保たれます。
制限事項:
- マージコミットが存在する場合、動作しません。
- コンフリクトが発生する操作は処理できません。
git history reword
git history reword <commit> は、特定のコミットのコミットメッセージを更新します。メッセージ用のエディタを開き、変更を保存して、その上に残りのコミットスタックを再構築します。
この操作はコミットメッセージのみを修正し、ファイルの内容は変更しないため、インデックスやワーキングツリーには影響を与えません。これにより、ユーザーは現在チェックアウトしていないブランチ上のコミットを書き換えることができます。
git history split
git history split <commit> は、単一のコミットを2つの別々のコミットに分割します。このプロセスはインタラクティブであり、git add -p と同様のハング・バイ・ハング(hunk-by-hunk)プロンプトを使用して、どの変更が最初のコミットに含まれ、どの変更が2番目のコミットに含まれるかを選択できます。
git rebase -i および Jujutsu (jj) との比較
git history は、インタラクティブ・リベースの最も頻繁に使用されるユースケースを、摩擦の少ない単一目的のコマンドへと簡略化します。しかし、これは他のシステムで利用可能なより強力なツールに完全な置き換わるものではありません。
| 機能 | git history |
git rebase -i |
Jujutsu (jj) |
|---|---|---|---|
| アトミックな操作 | はい (コンフリクト時に失敗) | いいえ (解消のために一時停止) | はい (コンフリクトは第一級オブジェクト) |
| 子孫ブランチの自動更新 | はい (すべてのローカルブランチ) | 限定的 (--update-refs) |
ネイティブ |
| ワーキングツリーへの影響 | 最小限 (reword/split の場合) | 高い (ツリーを書き換える) | ワーキングコピーはコミット |
| 複雑さ | 低い (単一コマンド) | 高い (手動でのリスト編集) | 中程度 (新しいメンタルモデル) |
コミュニティの洞察と実用的な検討事項
コミュニティの議論では、いくつかの重要なトレードオフと、これらの新しいコマンドに関するユーザーの経験が強調されています。
履歴のキュレーションの価値
一部の開発者は、Git の履歴を完璧にキュレーションすることは不要であると主張しており、マージ前にすべてのコミットを squash するアプローチがより効率的であると示唆しています。他の人々は、これらのツールを……