Git で特定のコミットを打ち消す!git revert の正しい使い方

開発現場で「あっ、このコミット間違えた!」という経験はありませんか。バグを含むコードをマージしてしまったり、仕様変更で不要になった機能をコミットしてしまったりと、Git を使った開発では避けて通れない問題です。
そんな時に頼りになるのが git revert
コマンドです。このコマンドを使えば、履歴を壊すことなく安全にコミットを取り消すことができます。特にチーム開発では、他の開発者に影響を与えずに問題のあるコミットを無効化できる、とても重要なコマンドなのです。
背景
Git における履歴管理の重要性
Git の最大の特徴は、プロジェクトの全ての変更履歴を詳細に記録し続けることです。この履歴管理により、いつ誰がどのような変更を行ったかを正確に追跡できます。
しかし、この履歴の扱い方を間違えると、チーム全体の開発に大きな混乱を招いてしまいます。特に共有リポジトリでは、履歴の一貫性を保つことが極めて重要になります。
以下の図は、Git の履歴管理の基本的な流れを示しています。
mermaidflowchart LR
commit1[コミット A] --> commit2[コミット B]
commit2 --> commit3[コミット C]
commit3 --> commit4[コミット D]
subgraph shared[共有リポジトリ]
commit1
commit2
commit3
commit4
end
shared --> dev1[開発者1のローカル]
shared --> dev2[開発者2のローカル]
shared --> dev3[開発者3のローカル]
コミット取り消しの様々な方法
Git でコミットを取り消す方法は複数存在します。主要な方法を整理すると以下のようになります。
方法 | 履歴への影響 | 使用場面 | 安全性 |
---|---|---|---|
git revert | 履歴を保持 | 共有済みコミット | 高 |
git reset | 履歴を改変 | ローカルのみ | 低 |
git rebase | 履歴を書き換え | ローカルでの整理 | 低 |
この中で最も安全で推奨されるのが git revert
です。なぜなら、既存の履歴を一切変更せず、新しいコミットとして取り消し操作を記録するからです。
git revert と git reset の違い
git revert
と git reset
の動作の違いを理解することは重要です。以下の図で、それぞれの動作を比較してみましょう。
mermaidflowchart TD
subgraph original[元の状態]
A1[コミット A] --> B1[コミット B]
B1 --> C1[コミット C]
end
subgraph reset_result[git reset の結果]
A2[コミット A] --> B2[コミット B]
C2[コミット C<br/>削除される]:::deleted
end
subgraph revert_result[git revert の結果]
A3[コミット A] --> B3[コミット B]
B3 --> C3[コミット C]
C3 --> R3[Revert C<br/>Cを打ち消すコミット]:::revert
end
classDef deleted fill:#ffcccc
classDef revert fill:#ccffcc
git reset
は履歴からコミットを削除してしまいますが、git revert
は新しいコミットを作成して変更を打ち消します。この違いが、チーム開発での安全性に大きく影響するのです。
課題
誤ったコミットが本番環境に反映されてしまう問題
本番環境にデプロイされた後でバグが発見されることは、開発現場では日常茶飯事です。このような状況では、迅速かつ安全にコミットを取り消す必要があります。
特に以下のようなケースでは、緊急度が高くなります。
- セキュリティホールを含むコードがデプロイされた
- データベースに悪影響を与える処理が実行される
- ユーザー体験を著しく損なう不具合が発生した
チーム開発での履歴改変によるコンフリクト
git reset
や git rebase
を使って履歴を改変すると、他の開発者のローカルリポジトリとの間で深刻なコンフリクトが発生します。
mermaidsequenceDiagram
participant Dev1 as 開発者A
participant Remote as リモートリポジトリ
participant Dev2 as 開発者B
Dev1->>Remote: git push (コミット C)
Remote->>Dev2: git pull (コミット C を取得)
Note over Dev1: git reset で<br/>コミット C を削除
Dev1->>Remote: git push --force
Note over Remote: 履歴が書き換わる
Dev2->>Remote: git push
Note over Dev2,Remote: コンフリクト発生!<br/>Dev2 にはまだコミット C が存在
このような問題を避けるためには、共有済みのコミットに対しては git revert
を使うことが重要です。
安全なコミット取り消し方法の選択
開発者が直面する課題は、状況に応じて適切な取り消し方法を選択することです。判断を間違えると、以下のような問題が発生します。
- チームメンバーの作業環境が壊れる
- 重要なコミット履歴が失われる
- マージコンフリクトが頻発する
- デプロイプロセスが停止する
解決策
git revert コマンドの基本概念
git revert
は、指定したコミットの変更内容と正反対の変更を新しいコミットとして作成します。これにより、元のコミットはそのまま履歴に残しながら、その変更を実質的に無効化できます。
基本的な動作原理を以下の図で説明します。
mermaidflowchart TD
subgraph timeline[タイムライン]
direction LR
commitA[コミット A<br/>ファイル追加] --> commitB[コミット B<br/>バグ修正]
commitB --> commitC[コミット C<br/>新機能追加]
commitC --> revertC[Revert C<br/>新機能を削除]
end
subgraph changes[変更内容]
original[+新機能のコード<br/>+テストファイル<br/>+ドキュメント]
reverted[-新機能のコード<br/>-テストファイル<br/>-ドキュメント]
original -.逆の変更.- reverted
end
commitC -.参照.- original
revertC -.参照.- reverted
新しいコミットで変更を打ち消すメリット
git revert
を使うことで得られるメリットは数多くあります。
履歴の透明性 全ての操作が履歴として記録されるため、後から「なぜこの変更が取り消されたのか」を追跡できます。
安全性 既存のコミットを削除しないため、他の開発者の作業に影響を与えません。
可逆性 revert 操作自体も後から取り消すことができます(revert の revert)。
履歴を保持しながら安全に取り消す方法
git revert
の実行プロセスは以下のようになります。
mermaidstateDiagram-v2
[*] --> 対象コミット特定
対象コミット特定 --> コマンド実行
コマンド実行 --> 変更内容確認
変更内容確認 --> コンフリクト発生?: コンフリクト?
コンフリクト発生? --> 手動解決: Yes
コンフリクト発生? --> コミット作成: No
手動解決 --> コミット作成
コミット作成 --> [*]
このプロセスにより、安全かつ確実にコミットを取り消すことができます。
具体例
単一コミットの revert
最も基本的な使い方は、特定の一つのコミットを取り消すことです。
まず、取り消したいコミットのハッシュを確認します。
bashgit log --oneline
出力例は以下のようになります。
abc1234 新機能: ユーザー登録機能を追加
def5678 修正: ログイン画面のバグを修正
ghi9012 追加: データベーススキーマを更新
特定のコミット(例:abc1234)を取り消すには、以下のコマンドを実行します。
bashgit revert abc1234
このコマンドを実行すると、エディタが開いてコミットメッセージの編集画面が表示されます。
bashRevert "新機能: ユーザー登録機能を追加"
This reverts commit abc1234567890abcdef1234567890abcdef123456.
# メッセージを編集してください
# 'git commit --amend' でコミットメッセージを変更できます
メッセージを確認して保存すると、revert コミットが作成されます。
複数コミットの一括 revert
複数のコミットを一度に取り消したい場合は、範囲を指定して revert できます。
以下は、直近の 3 つのコミットを取り消す例です。
bashgit revert HEAD~2..HEAD
または、特定の範囲を指定する場合:
bashgit revert abc1234..def5678
複数のコミットを revert する際の注意点を整理しましょう。
指定方法 | 動作 | 用途 |
---|---|---|
HEAD~2..HEAD | 直近 3 つのコミット | 最新の変更群を取り消し |
abc1234..def5678 | 指定範囲のコミット | 特定期間の変更を取り消し |
--no-commit オプション | 一括で処理 | 手動でコミット調整 |
--no-commit
オプションを使用すると、各 revert をまとめて一つのコミットにできます。
bashgit revert --no-commit abc1234..def5678
git commit -m "複数の機能を一括で取り消し"
マージコミットの revert
マージコミットを revert する場合は、どちらの親コミットに戻すかを指定する必要があります。
mermaidflowchart TD
main1[main: コミット A] --> merge[マージコミット M]
feature1[feature: コミット B] --> merge
feature2[feature: コミット C] --> merge
merge --> main2[main: コミット D]
subgraph parents[親コミット]
parent1[親1: main ブランチ<br/>コミット A]
parent2[親2: feature ブランチ<br/>コミット C]
end
マージコミットの revert では、-m
オプションで親を指定します。
bash# メインブランチ側に戻す場合(通常はこちら)
git revert -m 1 <マージコミットのハッシュ>
# フィーチャーブランチ側に戻す場合
git revert -m 2 <マージコミットのハッシュ>
どちらの親を選ぶかは、以下の基準で判断できます。
親 1(-m 1)を選ぶ場合:
- フィーチャーブランチの変更をすべて取り消したい
- メインブランチの状態に戻したい
親 2(-m 2)を選ぶ場合:
- メインブランチの変更を取り消したい
- フィーチャーブランチの状態に戻したい
revert の revert(取り消しの取り消し)
revert 操作を取り消して、元の変更を再び有効にすることも可能です。
bash# 最初に何かをrevert
git revert abc1234
# revert操作を取り消す(元の変更を復活させる)
git revert HEAD
このプロセスを図で表すと以下のようになります。
mermaidflowchart LR
original[元のコミット<br/>機能A追加] --> revert1[Revert<br/>機能Aを削除]
revert1 --> revert2[Revert Revert<br/>機能Aを再追加]
subgraph state[コードの状態]
state1[機能A有効] --> state2[機能A無効]
state2 --> state3[機能A有効]
end
original -.対応.- state1
revert1 -.対応.- state2
revert2 -.対応.- state3
この機能は、一時的に機能を無効化して、後で再び有効にしたい場合に便利です。
まとめ
git revert の適切な使い分け
git revert
を効果的に使うためには、以下の状況判断が重要です。
git revert を使うべき場面:
- 共有リポジトリにプッシュ済みのコミット
- 本番環境にデプロイ済みの変更
- チームメンバーが既に pull している変更
- 履歴を保持したい重要な変更
他の方法を検討すべき場面:
- ローカルでのみ作業している変更
- まだプッシュしていない間違い
- 作業ブランチでの試行錯誤
正しい選択により、チーム全体の開発効率を大幅に向上させることができます。
チーム開発での注意点
チーム開発で git revert
を使用する際は、以下の点に注意しましょう。
コミュニケーション revert 操作を行う前に、チームメンバーに影響を報告することが大切です。
コミットメッセージ なぜ revert を行うのか、明確な理由をコミットメッセージに記載しましょう。
bashgit revert abc1234 -m "セキュリティ脆弱性修正のため緊急revert"
テスト実行 revert 後は必ずテストを実行して、システムが正常に動作することを確認してください。
デプロイ計画 本番環境での revert は、デプロイ計画と合わせて慎重に実行しましょう。
git revert
は Git における最も安全で信頼性の高いコミット取り消し方法です。履歴を保持しながら変更を無効化できるため、チーム開発では欠かせないコマンドといえるでしょう。適切に活用することで、安心して開発を進めることができます。
関連リンク
- article
Git で特定のコミットを打ち消す!git revert の正しい使い方
- article
Cline で Git 操作を自動化する方法
- article
【トラブル解決】git push が拒否される原因と安全な対応手順
- article
Cursor × GitHub 連携:プルリク作成からレビューまで自動化する方法
- article
Git の fetch と pull の違いを理解してトラブルを回避する方法
- article
【保存版】Git のタグ(tag)の使い方とリリース管理のベストプラクティス
- article
React 開発を加速する GitHub Copilot 活用レシピ 20 選
- article
Prisma の公式ドキュメントを使い倒すためのコツ
- article
GitHub Actions × Node.js:テストとデプロイを自動化する
- article
Pinia × TypeScript:型安全なストア設計入門
- article
Obsidian デイリーノート活用術:毎日の思考ログを資産に変える方法
- article
Git で特定のコミットを打ち消す!git revert の正しい使い方
- blog
iPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
- blog
Googleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
- blog
【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
- blog
Googleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
- blog
Pixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
- blog
フロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
- review
今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
- review
ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
- review
愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
- review
週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
- review
新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
- review
科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来