Gitでしていた勘違い

Git Advent Calendar 2015 6日目のエントリーです。 昨日は oh-sky さんの aliasにできないならsub-commandにすれば良い でした


みなさんはgitで操作をした後、内部のグラフがどうなっているかを意識していますか? 自分はGitの中身を勉強するまでは漠然としたイメージしかもっておらず、なんとなく操作して失敗するたびに泣きたい気持ちになっていました

このエントリでは簡単な例を上げて以前自分が勘違いしていたことと間違いに気付いてからの話をしたいと思います

さて問題です

      E - F(topic)
     /
A - B - C - D(master)

(A〜FはSHA-1ハッシュ値、カッコで囲まれているのはブランチ名ということにしてください)

たとえば上のようなグラフがあったとき以下のコマンドを実行したらどうなるでしょうか

  • git rebase master topic
  • git branch -D topic

git rebase master topic

自分が思っていたのは以下のようなグラフでした (man git-rebaseをしてもこういう例になってる)

              E' - F'(topic)
             /
A - B - C - D(master)

しかし正確には以下のようなグラフになります

      E - F
     /
A - B - C - D(master)
             \
              E' - F'(topic)

topicブランチは移動しているものの元のE - Fのコミットは消えずに残っています もちろん、git checkout topicとしてもFは参照できませんが、SHA-1がわかれば rebase 前のコミットを参照できます

git branch -D topic

deleteだから当然以下のようにbranchにあるコミット全てが消えると思っていました

A - B - C - D(master)

正確にはこうなります

      E - F
     /
A - B - C - D(master)

こちらでもFはSHA-1さえわかれば参照することが可能です

自分は何を勘違いしていたのか

この例に限らず Gitにはコミットを消してしまうようなコマンドがない ということです (消せるのはbranchのみ)

これに気付いたときは結構な衝撃をうけました
削除することができないということは、何かを失敗しても 必ず元に戻すことが可能 ということだからです
それからは何をするにもビクビクしながらgitを使うようなことはなくなりました


自分がこのようなことに気付いたのはGitの中身を勉強しようと 実践 Git - 低レベルに知る Git を見て、その後 入門Git を読み直してからです
ぜひみなさんもGitの中身を見て今まで誤解していたことや、ぼんやりとしたイメージしか持てなかったことを改めてはいかがでしょうか