gitレポジトリの状態を前に戻すコマンドgit resetについて、覚えるために自分用メモ。
参考資料
-
git reset についてもまとめてみる - murankの日記
- 参考資料というか、これだけではよくわからなかった部分を今回整理してみました、という感じ
usage
git reset -hで出てくるusageはこんな感じ。
git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]
いろいろオプションがあるけれど、普通に使う分には、だいたい以下のものを把握してればいいみたい。
git reset [--soft | --hard] [HEAD | HEAD^]
次の項から、この[--soft | --hard]及び[HEAD | HEAD^]がどういう意味を持つのか、まとめてみる。
HEADとHEAD^
この部分は、「状態をどこまで戻すか」の指定をしている。HEADとHEAD^はそれぞれ、最新のコミットの位置・そのひとつ前のコミットの位置を指す。
ただしHEADは、ここの図では「どこまでコミットしているか」という意味で使われているので、すこしこんがらがった。そりゃぁ最新のコミットという意味なので、そういうことなんだけど。
なお、ここにはコミットのidを入れてももちろんOK。HEADとHEAD^は代名詞なんですね。
--softと--hard
git resetはともかく、状態を前に戻すコマンド。しかしgitにおける「状態」は、
- HEAD (現在の最新コミットの状態)
- index (何をaddしたか・addした時点でのファイルの状態)
- working tree (いま現在のファイルの状態)
と3つ考えられる。このうちのどれを取り扱うか指定しているのが、この--soft・--hardなどのオプションだ。
どのオプションを付けると、何が操作対象になるかは、以下の表の通り。
| HEAD | index | working tree | |
|---|---|---|---|
| --soft | o | ||
| (no option) | o | o | |
| --hard | o | o | o |
要するに、
- やってしまったコミット(だけ)をなかったことにしたかったら、
--soft - addもなかったことにしたかったら、オプションなし
- ファイルの変更自体をなかったことにしたかったら、
--hard
ということ。また言い換えると
- 現在のファイルの中身が変わっちゃ困るなら、
--hardはやっちゃダメ - addしたものを忘れられちゃこまるなら、オプションなしでは危ない。
--softをつけよう。 - コミット位置を変えたくないなら、
git reset使うな…ではなく、戻す先をHEADにしておけば安心ですね。
という感じ。
まとめ
分かってしまえば、
git reset <何を戻す?> <どこまで戻す?>
というだけの話だったんですね。納得。
まぁ、ミスを修正するためのコマンドにしてはややこしいっすよね。「ええっ! コミットをなかったことにされると困るぞ…!? git resetこわっ!」とか思ってました。
でもこういう理解をしておけば、「何をミスったのか」「どこまで戻れば帳消しにできるのか」だけ考えればコマンド打てるので、使えそうな気がしてきました。