Git Reset vs Git Revert:エンジニアのための安全な「やり直し」術

Git tutorial - IT technology blog
Git tutorial - IT technology blog

ResetとRevert:ミスを修正するための2つの異なるアプローチ

駆け出しの頃、データベースのパスワードが含まれた .env ファイルを誤ってサーバーにコミットしてしまったことがあります。焦ってすぐに git reset --hard を実行しました。結果、自分のPCからはコミットが消えましたが、チームの他の5人は履歴の不整合によりコードをプッシュできなくなってしまいました。これが、トラブルシューティングにおけるツールの選択ミスに関する最初の苦い教訓でした。

どちらのコマンドも以前の状態に戻すためのものですが、コミット履歴の扱い方が大きく異なります:

  • Git Reset: 日記に書いた内容を消しゴムで消すようなものです。コミットを最初からなかったかのように完全に削除します。
  • Git Revert: 「前の行の内容は間違いです。逆の操作をしてください」という訂正文を追記するようなものです。古い履歴は残したまま、変更を打ち消すための新しいコミットを追加します。

実用面でのメリット・デメリット比較

1. Git Reset – リスクを伴う「タイムマシン」

メリット: コミットログを非常にきれいに保てます。ローカル環境でまだプッシュしていないミスなら、Resetが最も早く証拠を消す方法です。

デメリット: maindevelop といった共有ブランチでは非常に危険です。Resetはプロジェクトのコミット履歴を書き換えます。同僚がすでに古いコードを取得している場合、Resetを行うと同期時に深刻なコンフリクトが発生します。

2. Git Revert – プロフェッショナルな手法

メリット: チーム開発において絶対的な安心感があります。過去のデータを一切削除しません。これにより、チームは「non-fast-forward」エラーに遭遇することなく、履歴の流れを維持できます。

デメリット: コミットリストが少し煩雑に見えることがあります。「Revert ‘Add login feature’」といったコミットが残るためです。5〜10回連続でリバートが必要になった場合、Gitログを確認するのが少し大変になります。

同僚に迷惑をかけないためのResetとRevertの選び方

数年にわたり2人から20人規模のプロジェクトを管理してきた経験から、私は以下のような鉄則を導き出しました:

  1. Git Resetを使う場面: 個人のブランチ(フィーチャーブランチ)で作業中かつ、GitHub/GitLabにプッシュしていない場合. また、プルリクエストを作成する前に、5〜6個の細かいコミットを1つの大きなコミットにまとめるのにも非常に便利です。
  2. Git Revertを使う場面: コードがすでにサーバーにあり、他のメンバーと同じブランチで作業している場合. これが全員のワークフローを壊さないための、最もスマートな解決策です。

現在の8人のチームでは、メインブランチへの force push を固く禁じています。この規律のおかげで、この1年間、履歴の不整合による緊急事態はゼロになりました。

詳細な実装ガイド

Git Resetの3つのレベルを使い分ける

意図しないコードの紛失を防ぐために、これら3つのフラグの違いを明確に理解する必要があります。

–soft: コードはそのままに履歴だけ戻す

このコマンドはHEADポインタのみを移動させ、書いたコードはすべてStaging Areaに残ります。これは、複数の小さなコミットを1つにまとめるのに最適な方法です。

# メッセージを修正するために直近のコミットをまとめる
git reset --soft HEAD~1

–mixed (デフォルト): コードは残すがaddされていない状態にする

フラグを指定しない場合のデフォルトモードです。コードは残りますが、Unstagedの状態になるため、再度コミットするには git add が必要です。

# ハッシュ値 abc1234 のコミットまで戻る
git reset abc1234

–hard: 痕跡を残さず削除 – 要注意!

このコマンドはすべての変更を破棄し、ソースコードを指定したコミットの状態に完全に戻します。そのコードが本当に不要であると確信がない限り、使用しないでください。

# すべてを破棄して完全にクリーンな状態に戻る
git reset --hard HEAD

Git Revertの使用方法

Revertはよりシンプルで安全です。誤ったコミットを見つけ、それを取り消す命令を出すだけです。

# ハッシュ値を確認するために履歴を表示
git log --oneline

# 誤ったコミットを取り消す(例:e4f5g6h)
git revert e4f5g6h

Gitは自動的にエディタを開き、リバートの理由を入力するよう求めます。保存して終了すれば完了です。もしコンフリクトが発生した場合は、通常のコードマージと同じように解決してください。

救済策:Reflogという名の命綱

誤って git reset --hard を実行し、1日分の作業が消えてしまいましたか?絶望するのはまだ早いです。Gitには reflog という、HEADポインタのすべての移動を記録する秘密のメカニズムがあります。

今すぐこう入力してください:

git reflog

実行したすべてのアクションのリストが表示されます。Resetコマンドを実行する直前のハッシュ値を見つけ、そのハッシュに対して再度Resetをかければ、コードは復活します。私はこの方法で、うっかりミスをしてしまったチームのジュニアメンバーを何度も救ってきました。

結論として一言:「ローカルならReset、公開済みならRevert」。この考え方をマスターすれば、ソースコードを完全にコントロールし、どんなトラブルにも自信を持って対応できるようになります。

Share: