誤ったgit コミット 取り消しを行うために git reset と git revert のどちらを使えばよいか迷ったことはありませんか。この2つのコマンドは「コミットを取り消す」という目的は同じですが、内部の動作がまったく異なります。間違ったコマンドを選ぶと、チームの共有リポジトリを破壊する危険があります。この記事では、判断基準となる1つのルールと、具体的な使い分けを解説します。
このシリーズの全記事
- 第1回:プログラミングエラーメッセージの読み方
- 第2回:VSCodeで「command not found: code」が出た時の解決方法
- 第3回:npmのEACCESエラーをsudoなしで安全に解決する方法
- 第4回:git commitでVimが開いたときにコミットをキャンセルする方法
- 第5回:git detached HEAD状態から安全に復帰する方法
- 第6回:git resetとgit revertの違いと使い分け【この記事】
- 第7回:git restoreで特定のファイルだけを過去に戻す方法
- 第8回:VSCodeのマージエディタでgitコンフリクトを解消する手順
- 第9回:.envをGitにコミットしてしまった場合の履歴からの完全削除
この記事でわかること
- git resetとgit revertの内部動作の違い
- 「リモートにプッシュ済みかどうか」という絶対的な判断基準
- 各コマンドの具体的な実行手順とチーム開発での注意点
比較サマリー
| 項目 | git reset | git revert |
|---|---|---|
| 動作 | コミット履歴そのものを書き換える | 打ち消しコミットを追加する |
| 使用場面 | ローカルのみのコミット取り消し | リモートにプッシュ済みのコミット取り消し |
| 他の開発者への影響 | 強制プッシュが必要になり、他の履歴と不整合が生じる | 履歴を追加するだけなので影響なし |
| 安全性 | ローカル限定なら安全 | 常に安全 |
絶対的な判断基準:リモートにプッシュ済みかどうか
コマンドを選ぶ際の判断基準は1つだけです。「取り消したいコミットがすでにリモートリポジトリ(GitHubなど)にプッシュされているかどうか」を確認してください。
- ローカルのみ(未プッシュ):
git resetを使う - リモートにプッシュ済み:
git revertを使う
git reset:ローカルの履歴を巻き戻す
git reset はコミット履歴そのものを書き換えます。まだ誰も見ていないローカルのコミットを取り消す場合に使います。
直前のコミットを取り消して変更をステージングに残す
git reset --soft HEAD~1
# 出力:(出力なし、コミットが取り消されてファイルの変更がステージングに戻る)
git status
# 出力:
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: app.py
直前のコミットと変更内容を完全に取り消す
git reset --hard HEAD~1
# 出力:
HEAD is now at abc1234 前のコミットメッセージ
注意
--hard オプションは変更内容も削除します。作業中のファイルへの変更が消えるため、慎重に使用してください。プッシュ済みのコミットに対して git reset を実行し、その後 git push -f(強制プッシュ)を行うことは、チームの全員のローカルリポジトリを破壊するため絶対に禁止です。
git revert:打ち消しコミットを追加する
git revert はコミット履歴を書き換えません。「取り消したいコミットと逆の変更」を行う新しいコミットを追加します。これにより、他の開発者の履歴と整合性を保ったまま変更を元に戻せます。
特定のコミットを取り消す
# まず取り消したいコミットのハッシュを確認する
git log --oneline
# 出力:
def5678 (取り消したいコミット)
abc1234 正常なコミット
999aaaa 最初のコミット
# 打ち消しコミットを作成する
git revert def5678
# 出力:(エディタが開くか、以下のメッセージが表示される)
[main ghi9012] Revert "取り消したいコミット"
1 file changed, 1 deletion(-)
打ち消しコミットをリモートに反映させる
git push origin main
# 出力:
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (2/2), 245 bytes | 245.00 KiB/s, done.
To github.com:user/repo.git
def5678..ghi9012 main -> main
なぜリモートの履歴を書き換えてはいけないのか
チーム開発では、他の開発者が git pull でリモートの最新状態を取得して作業しています。あなたが git reset でリモートの履歴を書き換えた場合、他の開発者のローカルリポジトリには「もう存在しないコミット」が残り、次回のプッシュやプルで深刻なコンフリクトが発生します。この状態の修復は困難であり、最悪の場合は他の開発者の作業内容が失われます。
まとめ
- コミット取り消しの判断基準は「リモートにプッシュ済みかどうか」の1点のみ
- 未プッシュのコミットは
git resetで履歴ごと取り消す。プッシュ済みのコミットはgit revert <ハッシュ>→git pushで打ち消しコミットを追加する - プッシュ済みの履歴を
git reset+ 強制プッシュで書き換えることは、チーム全員の環境を破壊するため絶対に行わない
シリーズナビゲーション:脱・初学者サバイバルガイド


コメント