まるノート

備忘録も兼ねて、様々なお役立ち情報をまとめています。

【Git】git init ~ git add を実行し「.git」の状態を調べてみた。


はじめに

Git の使い方を勉強中です。以前から使っているのだけど、よくわかっていないことが多く
最近改めて基本的なことから学習し直しています。

特にピンとこないのがコミットツリーとかブランチの概念図。

その次にピンとこないのが以下のような概念図。
例えばgithubを利用する場合、以下のような流れで追加したファイルや、
ファイルに対する変更内容を登録するってことはある程度知ってはいるつもり。

だけど多くのことがモヤモヤしているので、少しでも理解を進めるため、
まずはステージとかリポジトリとかが一体何者なのか、ということを丁寧に調べてみました。

※Gitはインストール済みの前提です。
(右クリックメニューで以下の内容が選択できる)


git init

とりあえず、空の作業フォルダを用意して右クリックメニューの「Git bash Here」を開き、
以下を実行。

$ git init


すると作業フォルダに「.git」なる隠しフォルダが生成される。

「.git」の中は以下のようナゾのファイル郡が見えるはず。
これらがgitのリポジトリやステージを構成するファイルになります。

以降、gitの操作を行うことで、これらのファイルがどうかわるか見てゆきます。
特に注目するのが「objects」フォルダ。初期状態はこんな感じ。


ファイル追加 ~ git add

次に何か適当なテキストファイルを作成してステージに追加してみます。

$ echo 'Hello world' > test.txt
$ git add test.txt


すると先程の「objects」フォルダ内にフォルダが追加されているはずです。

なかを見ると、、以下のようなファイルがあります。

これは一体何なのか、これは 先程git addで追加した
「test.txt」の内容 + 必要な追加情報を付与して圧縮したファイルになります。
「test.txt」の内容というのは今回の例だと「Hello world」になります。
ファイル名の情報はここにはありません。

ではファイル名やファイルのパスといった情報はどこに保存されているかというと、
「objects」フォルダと同じ階層にある「index」ファイルに書き込まれています。

よく見ると「objects」フォルダと「index」ファイルのみ更新日時が変わっているのがわかります。
つまり、gitのステージと言う概念を構成するのはこの2つであることが分かったのではないかと思います。


blob オブジェクト

ここで、先程確認した「objects」フォルダに生成された内容を解説します。 そのためにgit cat-fileというコマンドを利用します。-pを付与した場合「objects」フォルダ内の情報をはじめとする、 リポジトリに登録されている情報を見ることができます。

$ git cat-file [オプション] [ハッシュ値]


ではこのハッシュ値に何を指定すれば良いのか、
「objects」フォルダ内のフォルダ名と、中のファイル名をくっつけた名称になります。

とりあえず実行してみます。

$ git cat-file -p 802992c4220de19a90767f3000a79a31b98d0df7
Hello world


「test.txt」の内容が表示されました。

どういうことかというと、「Hello world」をハッシュ関数でハッシュ化して返してきた値の
頭2桁を「objects」フォルダ配下のフォルダ名に、残り38桁をファイル名にしている
ことになります。 この.git/objects配下の内容はblobオブジェクトと呼ばれ、 38桁のファイル名の方にはステージに追加したファイルの内容が圧縮されて保存されています。


index

次に「index」ファイルの方を見てみます。
git ls-files --stageというコマンドで「index」ファイルの情報を確認できます。

以下を実行すると、、

$ git ls-files --stage
100644 802992c4220de19a90767f3000a79a31b98d0df7 0       test.txt


先ほどのblobオブジェクトとファイルのパスが記述されています。
先頭の「100644」 はblobオブジェクトに対するアクセス権限を表しています。
※100は通常のファイル、644はrw-r--r--(自分は書き込み編集可能、グループメンバーや他人は閲覧のみ)を表す。

blobオブジェクトの後ろの数字「0」はマージコンフリクトなどが起こると変わるようですが今回はちょっと省略します…。

とりあえずgit init からgit add コマンドによってどんなことが起こるか、
ステージとは具体的にどんなものか、が結構わかってきたのではないでしょうか。
今回の記事では一旦ここまでにしますが、同じように git commit まで続けたいと思います。