git-resetは結局何を戻すのか

  • 229
    いいね
  • 1
    コメント
この記事は最終更新日から1年以上が経過しています。

 gitレポジトリの状態を前に戻すコマンドgit resetについて、覚えるために自分用メモ。

参考資料

usage

 git reset -hで出てくるusageはこんな感じ。

git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]

 いろいろオプションがあるけれど、普通に使う分には、だいたい以下のものを把握してればいいみたい。

git reset [--soft | --hard] [HEAD | HEAD^]

 次の項から、この[HEAD | HEAD^]及び[--soft | --hard]がどういう意味を持つのか、まとめてみる。

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こわっ!」とか思ってました。

 でもこういう理解をしておけば、「何をミスったのか」「どこまで戻れば帳消しにできるのか」だけ考えればコマンド打てるので、使えそうな気がしてきました。