Gitで過去のコミットに戻る方法!reset・revertの違いも解説

git
\ Gitがよく分からない初心者の方へ /
さわっておぼえるGit入門
Gitがよく分からない初心者でも、
この1冊で基本操作を一通り理解できます。
👉 Amazonで詳しく見る
Kindle Unlimitedなら無料で読めます
▶ 無料で読む(Kindle Unlimited)

今回は、Gitで過去のコミットに戻る方法について解説します。
Gitを使っていると、こんな場面ありませんか?

  • 以前の状態に戻したい
  • バグが出たので正常な状態に戻したい
  • 間違ったコミットをなかったことにしたい
  • reset / revert の違いが分からない

結論から言うと、安全に戻すなら git revert、履歴ごと戻すなら git reset を使います
ただし、使い方を間違えると履歴が消える・チームに影響が出るので注意が必要です。
リポジトリにpushしたあとか、前かで対応が異なります。

この記事では、初心者の方でも分かるように「安全な方法 → 危険な方法 → 使い分け」の順で解説します。

Gitで過去のコミットに戻る方法(結論)

Gitで過去に戻る方法をまとめると、主に3つです。

方法 コマンド 安全性 特徴
元に戻す(履歴を残す) git revert ◎ 安全 打ち消しコミットを作る
強制的に戻る git reset △ 注意 履歴を書き換える
一時的に戻る git checkout 状態を確認するだけ

一番安全:git revert(おすすめ)

最も安全なのがgit revertです。
git revertを使うと、コミットした内容を打ち消すコミットが作れます。

特徴

  • 履歴を消さない
  • チーム開発でも安全
  • push後でも使える

このような特徴があり、すでにpushしてしまっている場合は、他のチームメンバーが取得している可能性があるためrevertを使った方がいいです。
履歴を消したい場合は、チームメンバーに知らせた後に、後述するresetを使って、git push --forceしましょう。

使い方

git revert コミットID

git revert a1b2c3d

指定したコミットを打ち消す新しいコミットが作られます。

どういう仕組み?

A → B → C(現在)
        ↓
A → B → C → Cを打ち消すコミットDができる

現在の履歴に加えて、打ち消しコミットが作られます。
履歴はそのままなので、チームメンバーに取得されていても問題なくプッシュして大丈夫です。

履歴ごと戻す:git reset(注意)

git reset は強力ですが、注意が必要です。
resetを使うと、履歴も一緒に消すことができます。

特徴

このような特徴があります。

  • コミットをなかったことにする
  • 履歴が消える
  • push後は基本NG

どういう仕組み?

A → B → C(現在)
        ↓ reset --hard HEAD~1 を実行
A → B(Cが消える)

このように実行すると、履歴自体が消えます。

コミット自体がなくなるため、プッシュ後の使用は控えた方がいいです。
これは、ほかのチームメンバーが既に取得していて、ローカルとリポジトリの差分が合わなくなる可能性があるためです。
他のメンバーがそのコミットをベースに作業を始めている場合、強制的に履歴を消すと、他の人の環境でpushやpullができなくなる(競合が多発する)原因になります。

ひとりだけで使っているGitリポジトリであれば問題ないです。

よく使う3種類

よく使う操作の3種類です。

① soft(履歴だけ戻す)

git reset --soft HEAD~1
  • コミットだけ削除
  • 変更内容は残る

直近の1つ分のコミット履歴だけ消して、ファイルの変更内容は残ります。
「コミットコメントを間違えた」・「コミット漏れがあった」というときに、筆者もよく使っています。

② mixed(よく使う)

git reset HEAD~1
  • コミット削除
  • ステージも解除

こちらは、先ほどの状態と同じですが、ステージエリアからファイルが解除されます。
完全にコミット前に戻して、変更内容を確認し直したり、修正するときに便利です。

③ hard(危険)

git reset --hard HEAD~1

--hardオプションを使うと、コミット内容とファイル自体が消えてしまいます。
そのため、本当に必要のないコミットのとき以外には使わない方が良いです。

もしreset --hardで消してはいけないものを消してしまったら、git reflog コマンドで操作履歴を確認し、元の状態に戻せる可能性があります。
諦める前に試してみてください。

注意点(重要)

最後に注意点です。

resetについては、push済みのコミットに使うと、開発メンバーのローカルと食い違いがでる可能性があります。
少人数の場合には、ヒアリングして問題ないか確認し使っても良いでしょう。

基本的には、push済みの場合にはrevertを使った方が安全です。
リポジトリにプッシュする前(チームで共有前)であれば使っても問題ないです。

一時的に戻る:git checkout

過去の状態を「確認したいだけ」ならgit checkoutを使いましょう。

git checkout コミットID

この操作をすると、下記の2点の状態になります。

  • detached HEAD になる
  • そのまま作業するとブランチに属さない

ブランチに属していないため、そのまま作業を進めるのはやめましょう。
確認などが終わったら、ブランチに戻って作業するようにします。

安全に使う方法

git checkout -b new-branch コミットID

checkout時に新しいブランチを作って、作業するのもありです。
こうすると、指定した「コミットID」のときの状態で、「new-branch」が作られます。

コミットIDの確認方法

戻したい箇所のコミットIDを確認する方法です。
まずは対象のコミットを確認します。

git log

短く表示したい場合はこちらです。

git log --oneline

実際にコマンドを使うと、このように左にコミットIDが記載されています。

% git log --oneline

db0f9e5 (HEAD -> merge_test1) Merge branch 'merge_test2' into merge_test1
4502ca6 (merge_test2) コンフリクトテスト
72d8825 マージテストコンフリクト
ca4defd (origin/main, merge_branch, main) マージテスト
63fb320 (test_branch) ファイルに新規のテスト行を追加

どれを使うべき?(使い分け)

最後に使い分けについてです。
簡単にまとめると、下記になります。

  • とにかく安全に戻したい → git revert
  • ローカルだけで履歴整理 → git reset
  • 過去の状態を確認したい → git checkout

履歴は残したまま、戻したい場合にはgit revertを使っていきましょう。

履歴を消したい場合には、コミットを既にプッシュしたかを確認し、していない場合はgit resetを使うようにしましょう。
既にpushしている場合でも、ほかのメンバーが取得していなかったらgit resetした後にgit push --forceするのもありです。

まとめ

今回はGitで過去のコミットに戻る方法を確認していきました。

既にpushしたかどうかを確認して、git revertgit resetを使い分けましょう。
単純にコミット時点の内容を確認したい場合にはgit checkoutも有効です。

最終的に迷ったらrevertを使うのが安全です。

コメント