What you Learned?
- リモートのmain branchをPR merge前の状態に戻す。
-
git revert
コマンドの使い方。
Goal
- リモートのmain branchをPR merge 前の状態に戻す。
-
revert
コマンドを使う。
Contexts
- 何度かcommitしたbranchをリモートのmain branch にMergeした状態。
- これまでのcommitを無かったことにして、main branchを元の状態に戻したい。
What I did
Revertコマンドとは
- 特定のコミットを打ち消すコミットを作成するコマンド
公式 reference
git revert [--[no-]edit] [-n] [-m <parent-number>] [-s] [-S[<keyid>]] <commit>…
git revert (--continue | --skip | --abort | --quit)
# https://git-scm.com/docs/git-revert
Resetコマンドとの使い分け
git reset
コマンドはコミットを無かったことにするコマンド。正確にいうと
-
git reset --soft HEAD^
- 直前のコミットを取り消す。ステージングとWorking directoryは変化なし。
-
git reset --mixed HEAD^
- 直前のコミットとステージングを取り消す。Working directoryは変化なし。
-
git reset --hard HEAD^
- 直前のコミットとステージングとWorking directoryを全部取り消す。
これに対し、 revert
コマンドはcommitを打ち消すcommitを作成する。そのため、commitを無かったことにするのではなく、変更点をもとに戻すようなcommitを新しく作成するコマンド。
これは既にPRを出した後やリモートにmergeした後に打ち消したい時に使用する。
リモートに出してしまった後にresetを行うと、他の人がローカルにpullしたコードと整合性が取れなくなる可能性があるため、 reset
は使わず revert
を使う。
基本の使用例
公式referenceから使用例を参照。
- 特定のコミットを取り消したい場合、コミットIDを指定するか、
HEAD
からいくつ前のコミットを取り消したいかを指定する。 - もし複数コミットを取り消す場合は、どこからどこまでを取り消すかを指定する。
-n
オプションを使わない場合、各コミットを取り消すコミットメッセージを個別に入力することになる。同じ理由で複数コミットを取り消す場合は、-n
オプションを使って、最後に自分でコミットを作成する。-
revert -n
はコミットなしで revertするというオプション。
-
EXAMPLES
git revert HEAD~3
Revert the changes specified by the fourth last commit in HEAD and create a new commit with the reverted changes.
git revert -n master~5..master~2
Revert the changes done by commits from the fifth last commit in master (included) to the third last commit in master (included), but do not create any commit with the reverted changes. The revert only modifies the working tree and the index.
すでにコミットをMergeしてしまった場合
revert
でmergeを打ち消す場合には、 -m
オプションにてmainlineの番号を指定する。Mergeは2つ以上の親コミットを持つため、どちらの親を基準に変更を取り消すかを指定する必要がある、ということ。
ざっくりいうと、1がマージされたbranch (mainやmaster), 2がマージしたbranch (featureなど)になる。
親コミット確認方法
# 確認方法1:
git log
# "Merge: <commit id> <commit id>"と出てくる順番に1, 2
# 確認方法2:
git show --pretty=%P <commit>
> <commit id> <commit id>
#と出てくる順番に1, 2
今回は、リモートのmain branchに行っている複数のMergeと複数のCommitを取り消したいため、以下を実行。
git revert -n -m 1 <commit id>..HEAD
意味は
-
git revert
を行う。 -
-n
コミットをしない (最後に手動で行う、これをしないと打ち消すコミットごとにコミットを作ることになる) -
-m 1
Mergeをrevertして、親コミット 1 を元に戻す。 -
<commit id>..HEAD
からHEADまでを打ち消す。
Revert
中にエラーになる時がある。
error: revert is already in progress
hint: try "git revert (--continue | --abort | --quit)"
上記のエラーが出る時がある。これは既に revert
作業中の時、さらに revert
をすることができないということ。
その場合は、以下のいずれかによって作業中の revert
を完了させる。
-
git revert --continue
-
revert
操作を完了させる。
-
-
git revert --abort
-
revert
を中止させる。
-
-
git revert --quit
-
revert
一時停止させる。
-
Revert
中に conflictを起こす時もある。
複数のcommitを取り消すときに、conflictを起こす時もある。その時は以下の手順で解決する。
- 該当するファイルからコンフリクトを修正する。
- 該当するファイルをステージング。
git add <file name>
-
revert
を続ける。git revert --continue
参考
またさらに詳細が公式から用意されていたため、参照リンクを残しておきます。