現場ではSubVersionを使っており、gitはちょろっと触ったことがあったのみ。add→commitを繰り返して適度にpushしてpullリクエストを投げて、コンフリクトを起こしたら慌ててググるみたいな状態だったので、ちゃんと勉強しようと思った。
Gitの本質はcommitだ、というのはなんとなく知ってはいたものの、それがどういうことなのかきちんと理解していなかったので自分の知識定着も兼ねて記事にしておく。
まだまだ初心者なので、間違いがありましたらご指摘いただけると嬉しいですm(_ _)m
##commitは差分ではなくその時点のスナップショット
1.ワークツリーの変更分のみをgit add、git rmし、インデックス(ステージング)環境に反映
2.インデックスの内容をローカルリポジトリにcommit
という流れだからか、commitは変更差分だと思いがちだが、実際はインデックス環境のスナップショットを丸ごと取得している。
なので、後からcommitのSHA-1(commitした時に割り振られる長いやつ)を指定して前のバージョンに戻すことができる。
##branch=ただのポインタ
上記のとおりcommitすると、そのcommitを特定するためのSHA-1が割り振られる。
なので繰り返しになるが、SHA-1が分かっていれば特定のcommit時のスナップショットを取り出すことができる。
ただSHA-1は暗号学的関数というだけあり、長すぎて覚えられない。というか、そもそも覚える目的で作られていない。
これでは頻繁に確認したかったり、別に分けておきたかったりするcommitがあったとき、いちいちgit logでSHA-1を確認しなければならず面倒。
そこで、覚えておきたいcommitを指すポインタを作り、自由に名前をつけれるようにしたのがbranch。
ここで注意が必要なのは、SHA-1 != branchだということ。
SHA-1はあくまで特定のcommitと1対1になっており、生成されたSHA-1が指すcommitは不変。
branchはあるcommitを親とした子commitができた場合、子commitを指す。ポインタなので位置が変わる。(変えられる)
####1.コミット1が親のコミット2を作り、コミット2を起点とたdevブランチを作った場合
devブランチとHEAD(=現在地)はコミット2を指す。
####2.上記devブランチにコミット3を追加
コミット2に対するSHA-1は変わらず、devブランチとHEADの指す位置がコミット3に変わる。
今までbranch操作はちょっとヒヤヒヤしていたが、正体はポインタなので操作ミスをしてもまた新しいブランチを作れば良い。
それよりもcommitの変更内容がわかるようなコメントをちゃんと書くことの方が大切だと思った。
##鬼門checkout
checkoutはbranchを切り替えるときも使うし、編集したワークツリーを変更前の状態に戻すときも使うし、単語の意味をひくと「勘定を済ませて出ていく」とあるし、で、イマイチよく分からないコマンドだった。
しかし上記を踏まえると、checkoutはcommitせずにHEAD(=現在地)の位置を移動させるコマンド、という認識で良いのかなと。
####branchの切り替え
devブランチからmainブランチへcheckoutすると、mainブランチが指すコミットbにHEADが移動する。
####ワークツリーの変更を戻す(インデックスの状態にする)
左 :ワークツリーとインデックスは同じコミットを指しているが、ワークツリーのほうは変更を入れてしまっている。
中央:そこでcheckoutし、インデックスのコミットを指し直す
右 :すると変更がリセットされ、変更前のコミット3の状態に戻る
##参考
特に@JugglerShu@github さんの以下の記事はとても参考になりました。より詳細の情報が解説されており、実践形式で手を動かしながらできるので、Git初心者の方と先にSVNに慣れている方には特におすすめです。
https://github.blog/jp/2021-01-06-commits-are-snapshots-not-diffs/
https://ejje.weblio.jp/content/checkout