GitHub の PR で特定ファイルを誤って変更してしまったときの対処法

What I Learned

Pull Request 内の特定コミットから不要なファイル変更だけを取り除く方法を学んだ。git rebase -igit commit --amend を組み合わせることで、履歴を綺麗に保ちながら、過去のコミットをピンポイントで修正できる。

Details

問題の状況

PR を作成して diff を確認したところ、あるコミットで意図しないファイルが誤って変更されていた:

D  example/config.yaml    (削除扱い)

特定の設定ファイルやドキュメントなど、関係のないものがコミットに含まれてしまうケースはよくある。このままでは PR が正しくレビューできないため、該当コミットだけを修正する必要があった。

解決方針

今回の目的は以下の通りである:

これを実現するために、git rebase -i を使って該当コミットを直接編集し、git commit --amend で内容を書き換える方法を選んだ。

実際の手順

Step 1: 対象コミットの親から rebase を開始

対象コミット ID を abcd1234 として:

1git rebase -i 'abcd1234^'

rebase 用の画面が開き、次のような行が表示される:

pick abcd1234  Some commit message

これを次のように書き換える:

edit abcd1234  Some commit message

保存すると、abcd1234 のコミットで処理が一旦停止する。

Step 2: 不要な変更が混ざったファイルを元の状態へ戻す

該当ファイルを、コミットが加えられる前(親コミット時点)の状態に復元する。

例:example/config.yaml を元に戻す

1git checkout 'HEAD^' -- example/config.yaml
2git add example/config.yaml

これで誤って削除・変更されたファイルが復元され、修正内容としてステージングされる。

Step 3: コミット内容を修正(amend)

1git commit --amend

これにより、abcd1234 の内容が書き換えられ、本来必要だった部分はそのまま残り、誤って変更されたファイルだけが修正された状態の新しいコミットに置き換わる。

Step 4: rebase を続けて PR ブランチを更新

1git rebase --continue
2git push --force

これで、PR 上の対象コミットは完全に書き換わり、不要なファイル変更が含まれていない綺麗な状態に修正される。

Before / After の履歴比較

Before(誤ったファイル変更が入り込んでいた状態)

* abcd1234   ← このコミットに example/config.yaml の不要な変更が入っていた
|
* 7890fe12
|
...

After(コミット内容を正しく修正した状態)

* abcd1234'  ← example/config.yaml の誤った変更が取り除かれた
|
* 7890fe12
|
...

コミット ID は書き換えられるため別物になるが、履歴の流れそのものは保たれたままになる。

得られた知見

特定のコミットだけ修正したい場合は rebase -i が最適

Revert を追加して帳尻合わせする方法は簡単だが、履歴が二重になり PR が読みづらくなる。今回の方法は非常にスッキリする。

rebase と amend を組み合わせると過去を綺麗に直せる

コミットするべきでなかった変更を、まるで最初から存在しなかったかのように修正できる。

force push は PR ブランチ限定なら問題なし

他の人が使っていないブランチであれば履歴書き換えは安全である。

References