20190430追記
わかりにくい表現を修正しました。
内容の変更はしていません。
追記ここまで
ちょこちょこ使う機会はあったのですが、いまいち使いこなせていなかったrevertについて改めて調べました。
#revert とは
既存のコミットを取り消すためのコマンドです。
「取り消したいコミットを打ち消すようなコミットを新しく作成する」という処理によって、既存のコミットを取り消します。
新しくコミットを追加しているだけなので、既存コミットの履歴が消えるわけではありません(コミットログをみると残っています)。
どんな変更があったのかということが(revertしたということも含めて)残るので、リモートにpushされて公開されているコミットに対しても安全に使うことができます。
「既存のコミットを元に戻す」という点について、同じような機能を持つコマンドにreset
が存在します。
reset
コマンドは、「コミットを取り消した」というコミットが残りません。特にリモートにpush済みで公開されているコミットに関して使うことはNGです。気をつけて使用しましょう。
また、revert
コマンドは特定のコミット
を元に戻すコマンドです。
指定したコミット以降に行なわれた処理を全て戻す(この機能はreset
コマンドに含まれます)わけではありません。
#コマンド
###特定のコミットを取り消す
$ git revert <commit>
コミットIDを指定することで、そのコミットを打ち消すようなコミットが新しく追加されます。
コードは、そのコミットがなかったときの状態になります。
revertコマンドを実行するとエディタが開き、コミットメッセージを編集することができます。
###コミットメッセージ編集
revertコミットを行なうときに、コミットメッセージの編集を行なうかどうかをオプションで指定できます。
コミットメッセージを編集する(オプションを何も付けない場合はこちらになります)
$ git revert <commit> -e
or
$ git revert <commit> --edit
コミットメッセージを編集しない(エディタを開かない)
$ git revert <commit> --no-edit
###コミットしない
revertコマンドを使用するとコミットまで行なわれますが、indexに戻すだけでコミットを行なわないようにすることもできます。
複数のコミットをrevertするときに、一度にコミットすることができるので便利です。
$ git revert <commit> -n
or
$ git revert <commit> --no-commit
###マージコミット
マージコミットを取り消そうとした場合、マージした2つのコミット(親)のうちどちらに戻すのかを指定する必要があります。
-m
オプションの後に戻したい親を数字(基本的に1もしくは2)で指定し、revert
を実行します。
$ git revert -m 1 <commit>
git show
コマンドやgit log
コマンドで対象のマージコミットを見ると、親の数字(1もしくは2)がわかります。
$ git show
commit xyz
Merge: 1a1a1a 2b2b2b #ここに注目
Author: xxxx xxxx
Date: Thu Jul 13 09:00:00 2017 +0000
Merge commit
revert
したいマージコミットが、この「xyz」という番号のコミットだとします。
このマージコミットは、「1a1a1a」というコミットに「2b2b2b」というコミットがマージされてできたものです。
番号は、ログを表示させたときの、「Merge:」という行に書かれている順番に1、2とつきます。
この場合は、「1a1a1a」の番号が1、「2b2b2b」の番号が2となります。