git revert

コマンドの概要

指定したコミットの差分を逆方向にして新たにコミットを作成するコマンド。コミットを取り消したいときに使用する。
「revert」とは「もとに戻す」、とか「逆戻り」という意味。対象に指定したコミットの変更差分を逆にして新たにコミットを作成する。「A+B+C」に「A+B+C-B」として「-B」を加算することによりBをなかったことにするイメージ。

コマンドの使い方

1$ git revert <commit>

ワーキングツリーに変更がない状態でないと実行できないが、コミットを指定してコマンドを実行すると、指定したコミットの差分を逆にしたコミットが作成される。

1$ git revert -n <commit>

git revertにより新たなコミットを作成するのではなく、インデックスに展開するオプション。複数のコミットをまとめてgit revertする際などに利用する

マージコミットの revert

マージコミットを対象としてもgit revertは使用できる。マージされたブランチのコミットを逆にして新たにコミットを作成するため、マージがなかったものとして機能する。
mainブランチでコミットA,B、featureブランチでコミットC,Dという状態でmainブランチでfeatureブランチをマージすると、

gitGraph commit id:"A" commit id:"B" branch feature checkout feature commit id:"C" commit id:"D" checkout main merge feature id:"E:(C,D)"

マージコミットE:コミットCとコミットDの変更 HEAD:コミットA,B,E(C,D)での変更 Eのマージコミットを対象としてgit revertすると

gitGraph commit id:"A" commit id:"B" branch feature checkout feature commit id:"C" commit id:"D" checkout main merge feature id:"E:(C,D)" commit id:"F:(-C,-D)" type:reverse

mainブランチのHEAD:コミットA,B,E(C,D),F(-C,-D)
となりコミットA、Bの差分のみが含まれマージを取り消したように機能する。
ただし、featureブランチで開発を続け、マージできる状況になったと判断、マージすると

gitGraph commit id:"A" commit id:"B" branch feature checkout feature commit id:"C" commit id:"D" checkout main merge feature id:"E:(C,D)" commit id:"F:(-C,-D)" type:reverse checkout feature commit id:"G" commit id:"H" checkout main merge feature id:"I:(A,B,G,H)"

マージコミットIにはコミットG、Hしか含まれず、コミットC、Dは含まれないことになる。
なぜかというと、 revertコミットFはgit mergeを取り消ししたのではなく、git mergeされた差分(コミットE)の逆の差分で新たに"コミット"されているため、コミットA、Bはすでにmasterブランチにマージされているから。
あらためてコミットC、D、G、Hの内容をマージするには、revertコミットFをgit revertすればよい。

gitGraph commit id:"A" commit id:"B" branch feature checkout feature commit id:"C" commit id:"D" checkout main merge feature id:"E:(C,D)" commit id:"F:(-C,-D)" type:reverse checkout feature commit id:"G" commit id:"H" checkout main merge feature id:"I:(A,B,G,H)" commit id:"J(C,D)" type:reverse