【Git】git コミット 取り消しを初心者向けにわかりやすく解説
はじめに
皆さんはソースコードを管理するときに Git を使うことが多いのではないでしょうか。
複数人で開発を進めるときにも、バージョン管理ツールであるGitは欠かせません。
しかし、間違った内容をコミットしてしまったり、直前のコミットをやり直したくなったりすることが意外とよく起こります。
こうしたシーンで役立つのが、コミットを取り消すための操作です。
Gitにはいくつかの方法があり、使い方を誤ると混乱を招きがちです。
今回は、初心者の方にもわかりやすいように、具体的なコマンド例と実務での使い方を踏まえて丁寧に解説していきます。
この記事を読むとわかること
- コミットを取り消すとは何を意味するのか
- 取り消しを行う前に知っておくべきGitの仕組み
- 代表的な取り消し方法のやり方(revert、reset、restore)
- push後のコミットを取り消す際の注意点
- 実務で頻出する取り消しケースとそれに伴うリスク
コミットを取り消すとは?
コミットを取り消す操作を「過去の変更をなかったことにする」イメージだけで捉える方も多いかもしれません。
しかし実際には、特定の履歴を上書きする操作と、取り消し専用の新たな履歴を作る操作とで方法が異なります。
たとえば「修正ファイルをコミットした直後に、あやまって不要なファイルまで混ぜてしまった」というケースを想像してください。
すぐに気づいたなら「過去の状態に戻したい」、ただし履歴を破壊してしまうと後で混乱を招くかもしれない。
こうした場面で安全に履歴を戻すために、Gitにはいくつかの取り消し手順が用意されています。
最初に、それらのコマンドを触る前に知っておくべきGitの仕組みと背景を確認しておきましょう。
取り消し前に理解しておきたいGitの仕組み
Gitはコミットの履歴を時系列で記録する仕組みを持っています。
それぞれのコミットは、特定の状態を指し示す「スナップショット」に近いものです。
1. コミットID
各コミットには一意のID(ハッシュ値)が割り振られます。
これをもとに過去の状態をたどれるため、特定のコミットだけを取り出して比較や復元ができます。
2. ブランチ
コミットの連続した流れをブランチが表し、現在どのブランチ上で作業しているのかでコミット先が決まります。
間違ったブランチで作業を進めていた場合も、取り消しをする前にブランチ構造を把握すると混乱が少なくて済みます。
3. リモートリポジトリとローカルリポジトリ
チームで開発している場合は、ローカルで行ったコミットをpushすることでリモートと共有します。
リモート上のコミットを取り消す際は、別のメンバーがすでにそのコミットを取り込んでいる可能性があるため、より慎重に取り扱う必要があります。
誤ったコミットを消す操作の前に、「自分がどのブランチで作業しているか」「コミットがすでにpushされているか」を確認しておくのがおすすめです。
コミットを取り消す主な方法
コミットを取り消す代表的なコマンドにはrevert、reset、restoreがあります。
ここでは、それぞれどんな特徴があり、どんな場面で使うのかを見ていきます。
git revert
既存の履歴を残しつつ、新たなコミットを作って取り消す方法です。
元のコミットを「打ち消す」反映を上書きコミットとして行うため、履歴が破壊されません。
git revert <コミットID>
例えば、直前のコミットを取り消すだけなら git revert HEAD
と指定できます。
新しいコミットが生成されるため、過去の履歴をたどったときに「どこで何を取り消したのか」を明確に追跡しやすいのがメリットです。
一方で、revertしたコミット自体を再度revertするとややこしくなるため、一連の履歴をコンパクトに保ちたい場合には不便さが感じられるかもしれません。
git reset
履歴を指定した位置まで戻す方法です。
たとえば git reset HEAD~1
とすると、今いるブランチの履歴を1つ前のコミットに戻すことができます。
ただし、この操作はブランチ上の履歴そのものを書き換える点に注意が必要です。
git reset --soft HEAD~1 # コミットだけを取り消す git reset --mixed HEAD~1 # コミットとステージングも取り消す git reset --hard HEAD~1 # ファイルの変更も含めて完全に取り消す
--soft
はコミットを取り消すだけで、作業ツリーの内容はそのままです。
--mixed
ではステージングまで外れるので、差分はワークツリーに残ります。
--hard
は差分ファイル自体も消え、まさに「なかったこと」にするイメージです。
実務では、ローカルでの修正段階で利用するケースが多いです。
pullリクエストを出す前に「コミットをやり直したい」と感じたときは、resetで履歴を巻き戻してから改めてコミットするほうがスッキリします。
すでにpush済みのコミットに対してresetを使うと、他メンバーと履歴が食い違って混乱する可能性があります。
もしリモートに共有されているコミットの場合は、revertのように履歴を壊さない方法を選ぶのが無難です。
git restore
比較的新しい操作として登場したのが git restore
です。
これは「ワークツリーやステージングエリアに対して、特定のコミットの状態を復元する」コマンドで、resetよりも限定的に変更加えることができます。
# ステージングを取り消す場合 git restore --staged <ファイル名> # 変更ファイル自体を取り消す場合 git restore <ファイル名>
ただし、コミット丸ごとを取り消すというより「ファイル単位」で内容を元に戻すイメージで利用します。
「コミットそのものを消す」というよりも、「特定のファイルだけ前の状態に戻したい」という場面で使われることが多いでしょう。
push後のコミット取り消し
コミットをローカルで作成した段階ならば、resetで巻き戻すなど自由度が高いです。
しかし一度pushした後に取り消したい場合は、別のメンバーと履歴を共有している可能性があるため、むやみにresetを使うと履歴が食い違ってしまいます。
そうした状況では git revert
を使って取り消し専用のコミットを作成し、元のコミットを取り消したことを履歴に明示するのがおすすめです。
リモートで作業しているメンバーがいても、revert操作であれば相手側とコンフリクトしづらいですし、履歴のつながりも壊れません。
どうしても過去のコミットを消し去りたい場合に、push --force
を使って強制的に上書きする方法があります。
ただし、これは慎重に使わないと共同作業しているチームメンバーに大きな影響を与えるため、リポジトリの運用ルールを守った上で行うようにしましょう。
実務で多い取り消しのケース
Gitを実際に使っていると、コミットを取り消したい典型的なケースがいくつかあります。
それぞれどの方法を選ぶべきか考えてみましょう。
1. コミットメッセージだけを修正したい
単純にメッセージを直すだけなら、git commit --amend
で再コミットするのが便利です。
修正したいコミットが直前のもので、まだpushしていない場合はこれで十分でしょう。
ただし、すでにpushしていると他のメンバーの履歴に影響を与えるので、慎重に扱ってください。
2. ファイルを誤って混在させたのでやり直したい
例えば、「変更する予定のなかった設定ファイル」を誤ってコミットに含めてしまったケースです。
まだローカルなら git reset --soft HEAD~1
などでいったん差分を戻して、再度正しいファイルだけステージングしてコミットし直すことがよく行われます。
すでにpushしてしまった場合は git revert
を使う方が安全です。
3. 大きな履歴改変が必要になった
プロジェクト方針が急に変わって、大量のコミットをまとめてやり直したい。
こうしたケースではブランチごと作り直すのが一般的ですが、もしpush済みコミットが多い場合は履歴の食い違いに気をつけましょう。
必ずチーム内で相談してから決定するのがおすすめです。
複数のコミットをまとめて取り消す場合は、revertに複数のコミットIDを指定するか、インタラクティブリベース(git rebase -i
)などを使うやり方もあります。
ただしリベースは操作ミスでコンフリクトが起きやすいため、初心者の皆さんは慎重に取り組んでください。
まとめ
Gitのコミットを取り消すときは「どの段階でのコミットなのか」「push済みかどうか」をまず確認してから、最適なコマンドを選ぶことが大切です。
ローカルで完結するなら reset
や restore
が便利で、リモート共有後なら revert
で履歴を安全に残しつつ取り消す方法がおすすめです。
また、実務では履歴を壊してしまうと、他のメンバーの作業に大きな影響が及ぶ可能性があります。
チームで作業する際はrevertを基本とし、resetやforce pushなどの操作は慎重に判断しましょう。
こうしたコミットの取り消し操作を正しく扱えるようになると、慌てて余計なブランチを作る必要も減り、よりスムーズな開発ができるようになるはずです。
ぜひ今回の解説を参考にして、Gitを使ったバージョン管理の精度を高めてみてください。