revertとresetの違い
コミットを戻したい時にgit revert
とgit reset
のどちらを使うか迷うyamakawa00です。
忘れないようにブログにまとめておきます。
前提条件 - commitができる。 - conflictが理解できる。
現在の状態
まずは、現在のブランチの状態です。
HEADがコミットハッシュ「4」にある状態です。
「3」にバグがあり、そのコミットを消したい状態です。
revert
1つ以上の既存のコミットがあれば、関連パッチが導入した変更を元に戻し、それらを記録する新しいコミットをいくつか記録します。これには、作業ツリーがきれいである必要があります(HEADコミットからの変更はありません)。
公式ドキュメントを見てもよくわかりませんね...
わかりやすく図にして見ました!
$ git revert [3のコミットハッシュ]
git revert
とは、指定したコミットハッシュを打ち消すコミットを新たに行う行為をです。
上記の例では「3」のコミットを打ち消しています。
ただし基本的には、直前のコミット(つまりHEAD)を打ち消すために用いられます。
なぜ直前のコミットに適応するかというと、上記の図のように直前ではないコミットを打ち消すとコンフリクト(衝突)するからです。
revertのコンフリクト
「3」のコミットで「2」の変更点を消し、「4」のコミットで「3」の変更点を消すとどうなるでしょうか?
答えはコンフリクト(衝突)します。
実際にコンフリクトしたファイルは、こんな感じです。
diff --cc README.md index 6a1769f,0c4a8b1..0000000 --- a/README.md +++ b/README.md @@@ -1,2 -1,2 +1,6 @@@ ++<<<<<<< HEAD +4番目のcommit ++======= + 2番目のcommit ++>>>>>>> parent of 6c3bbd4... 3
コミットとは、コードの歴史を表すものです。
中学生の黒歴史を隠したいからといって、中学3年間を抹消すると、どこかで綻びが生じるので気をつけましょう。
reset
現在のHEADを指定された状態にリセットする
ことです。
ここでは、HEADを「2」に戻してみましょう。
$ git reset --hard [2のコミットハッシュ]
これで、HEADは「2」になっています。
「3」「4」は削除されます。
(厳密に言えば削除はされずに記録は残っています。ここから復元も可能です。)
reset --hard
とreset --soft
reset
には--hard
と--soft
の二つのオプションが存在します。
$ git reset --hard [コミットハッシュ] $ git reset --soft [コミットハッシュ]
--hard
は、現在のファイルの状態をHEADの位置の指定コミットまで復元します。
--soft
は、現在のファイルは特に変更せずに、HEADの位置を指定コミットまで移動します。
つまり--soft
は強くてニューゲーム状態です
【まとめ】revertとresetの違い
最後に両者のメリット、デメリットをまとめてみます。
どちらを使えばいいかはケースバイケースでしょう。
コマンド | メリット | デメリット | 使用ケース |
---|---|---|---|
revert | コミットログ自体は残っているので、revertの取り消しが容易 | 基本的には、直前のコミットの打ち消ししかしない方が良い。なぜなら、コミットの整合性が取れなくなってしまうからである。 | 直前のコミットにバグがあるので消したい時 |
reset | HEADの位置を大幅に移動できる。 | 以前のコミットを復元するのが少し手間 | 直前のコミットではないものにバグがある |