LINEで現役エンジニアに直接質問してみよう!登録無料

gitの変更履歴をrollback(取り消し)して、元に戻す方法を解説

gitはファイルすべての変更履歴を「コミット」という単位で管理しています。ですので、変更履歴をさかのぼって、コミット単位でrollbackをすることが出来ます。今回は、その2種類のrollback方法について解説します。

gitの変更履歴をコミット単位でrollbackする

gitをコミット単位でrollbackするには、3種類の方法があります。

  • git revertで変更履歴を打ち消すコミットを作成する
  • git resetで直前の変更履歴を強制的に削除する
  • git rebaseで変更履歴を操作して強制的に削除する

git revertで変更履歴を打ち消すコミットを作成する

この方法は、コミットされた変更内容を打ち消すようなコミットを新たに作成し、rollbackをする方法です。

この方法の良いところは、いつどんな目的で誰がrollbackしたのかでさえも、履歴として残せるところです。一番簡単で安全で、おすすめです。

どのコミットをrollbackするのかは、コミットハッシュで指定します。直前のコミットであれば、コミットの先頭を意味する「HEAD」を使うことも出来ます。

git revert
# 直前の変更内容を打ち消すようなコミットを作成する
$ git revert HEAD

# コミットハッシュ「c346798」を打ち消すようなコミットを作成する
$ git revert c346798

最後にrollbackをリモートリポジトリに反映させるため、git pushをしましょう。

git push
$ git push

git resetで直前の変更履歴を強制的に削除する

コミットしたのがつい先程で、まだgit pushをしていないのであれば、git resetを使ってrollbackする方法が良いと思います。この方法を行うと、直前のコミットが強制的に削除され、そもそも無かった事になります。

この方法を使うと、コミットが汚くなりづらいというメリットはありますが、複数人で開発を行っている際には、他人も使っているブランチに影響を及ぼしてしまわないように注意を払うことが大事です。もし、影響を与えてしまうと、「いつの間にかブランチが消えてしまったり」「今までの変更履歴を別のブランチに移動させる」などの面倒な対応が必要になるときも出てきます。

git reset
# 直前の変更履歴を強制的に削除する(変更したファイルの内容はそのまま)
$ git reset --soft HEAD

変更履歴だけではなく、変更したファイルの内容も同時に削除したい場合は--hardオプションを使います。

git reset
# 直前の変更履歴と変更したファイルの内容を強制的に削除する
$ git reset --hard HEAD

git reset --hardはよく確認してから使うようにしましょう。普段、必要になる場面は殆どありません。大抵は、git reset --softgit resetの組み合わせで安全に同じような事が出来ます。

最後にrollbackをリモートリポジトリに反映させるため、git pushをしましょう。ただし、過去の歴史を書き換えているので、-f(force)オプションが必要になります。

git push
$ git push -f

git rebaseで変更履歴を操作して強制的に削除する

git rebaseを使うと、2つ以上前のコミット履歴を編集することが出来ます。その機能の一部を利用してコミットを削除出来ます。

STEP.1
削除したいコミットを探しましょう

削除したいコミットのハッシュ値を見つける必要があります。見つける方法はここでは解説しませんが、githubやgit logで探す方法があります。

STEP.2
削除したいコミットの1つ前のコミットハッシュをメモしましょう

ここがgit rebaseで重要なポイントです。削除したいコミットハッシュ値ではなく、更に1つ前のコミットハッシュ値をメモする必要があります。

c3367281d3598732357904e0272730562e7b7997
STEP.3
メモしたハッシュ値をgit rebaseで実行する

そして、メモしたハッシュ値をつかってgit rebaseを実行します。

git rebase
# メモしたハッシュ値で git rebase を実行する
git rebase -i c3367281d3598732357904e0272730562e7b7997
STEP.4
一番上の行を削除する

そしたら、エディタが開いて次のような画面になります。行ごとにコミットを表していて、上のコミットほど古いのを表しています。

git rebase
pick 4570712 Added hogehoge.txt 
pick c336728 Update index.html
pick 208b652 Update main.css 
pick f8a05d3 Update main.js 

# Rebase f8a05d3..208b652 onto f8a05d3
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

一番上のコミットが今回削除したいものになっているかと思いますので、それを行ごと削除します。

git rebase
pick c336728 Update index.html
pick 208b652 Update main.css 
pick f8a05d3 Update main.js 

# Rebase f8a05d3..208b652 onto f8a05d3
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

このようになったら、保存してエディタを閉じましょう。そうれば後はgitが自動的に処理を完了してくれます。

STEP.5
git pushをしてコミットをリモートリポジトリに反映させる

最後にrollbackをリモートリポジトリに反映させるため、git pushをしましょう。ただし、過去の歴史を書き換えているので、-f(force)オプションが必要になります。

git push
$ git push -f
この記事を書いた人

自身がプログラミングを独学で勉強し始めて躓いた経験を元に、これから勉強をする人に向けに「イラスト多めでわかりやすい記事」にこだわって情報を発信しています。

現在はフルスタックエンジニアとしてサービス開発などのお仕事をしています。