16 ポイント 投稿者 GN⁺ 2024-09-27 | 2件のコメント | WhatsAppで共有
  • 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 を実行したりする代わりに、次を行う:
    1. git add $FILES_YOU_FIXED
    2. git absorb --and-rebase
  • git absorb は、どのコミットを安全に修正できるか、そして各 staged 変更がどのコミットに属するかを自動的に識別する
  • その後、これらの変更に対する fixup! コミットを作成する
  • --and-rebase フラグを使うと、これらの fixup コミットは対応するコミットに自動的に統合される
  • 信頼できない場合は、出力を手動で確認してから、git 組み込みの autosquash 機能を使って feature ブランチに fixup を統合できる

インストール

  • 最新のタグ付きリリースからアーティファクトをダウンロードしてインストール可能
  • Windows、MacOS、Linux 向けのアーティファクトを提供

使い方

  1. 吸収させたい変更を git add で追加
  2. git absorb を実行
  3. 結果に満足したら git rebase -i --autosquash を実行
  4. 満足できなければ git reset --soft で前の状態に戻す

How it works (roughly)

  • git absorb は、2 つのパッチ P1 と P2 が可換かどうかを確認する
  • デフォルトでは直近 10 件のコミットを対象にする
  • インデックス内の各ハンクについて、そのハンクが最新コミットと可換かどうかを確認する
  • 可換でないコミットが見つかったら、そのハンクを fixup コミットに変換する

Configuration

Stack size

  • デフォルトでは直近 10 件のコミットを対象にする
  • より多くのコミットを対象にするには、.gitconfigmaxStack の値を設定

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件のコメント

 
GN⁺ 2024-09-27
Hacker Newsの意見
  • git absorbを使っている人たちは、このツールは非常に便利だと考えている

    • 複数のコミットを含むPRがCIで失敗したとき、git absorbは自動的に正しいコミットを見つけてくれる
    • 手動でコミットを探す手間を減らしてくれる
    • 誤検出はほとんどなく、見逃しが起きた場合は手動で対処すればよい
    • PRは1つのコミットであるべきだという意見もあるが、常にそうとは限らない
    • GitHubでは論理的に小さなコミットが好ましい
  • git commit --fixup用のエイリアスを使って満足している

    • 現在のブランチのコミットを表示し、fzfを使って選択できる
    • 選択したコミットをもとにfixupコミットを作成する
  • git absorbを使ってみたが、親コミットを誤って選ぶことが多かった

    • 手動でコミットを探したほうがよかった
    • コミット履歴を完全に制御することを好む
    • このツールは魔法が多すぎる
  • git --fixupgit rebase --autosquashを使ったことはないが、有用そうに見える

    • git-absorbはさらに一歩進んでいるようだ
    • READMEでは、特定の状況で正確に何をするのかが明確ではない
  • コミットと履歴を書き換えることには懐疑的

    • ミスを修正して新しいコミットを作り、そのまま進めばよい
  • magitを使うと簡単にfixupコミットを作れる

    • Emacsを使わなくても、magitを使うために維持する価値がある
    • vscodeユーザーにはEdamagitがよい
  • git commit --fixupgit rebase --autosquashを知った

    • インタラクティブなgit rebaseはお気に入りのGitツールだ
    • 完璧に論理的で原子的なコミットを作るのに役立つ
    • しかし、このような履歴編集がときには裏目に出ることもある
  • git rebase -iはさまざまな要求を満たしてくれる

    • squash、fixup、reword、deleteコミットをインタラクティブに行える
    • gitを使うすべての人が学ぶべきだ
  • 超きれいなコミット履歴に執着するのは理解できない

    • コミット履歴をそんなに頻繁に詳しく確認するのか疑問だ
  • 直近10件のコミットから、衝突なしで修正可能なコミットを選ぶという発想が理解できない

    • 衝突を解決しながらfixup^をよく使う
    • ターゲットのコミットを自動選択することは信用していない
 
roxie 2025-05-18
  • 超きれいなコミット履歴に執着するのは理解できない
    • そんなに頻繁にコミット履歴を細かく確認するのか疑問だ

このコメント、刺さりますね。fixup / autosquash を少し触ってみたんですが、気にしているのは自分だけなのかなと思って、ちょっと虚無感が来ました...