LoginSignup
0
0

最初のgitの動作を図で理解する1

Last updated at Posted at 2024-01-03

はじめに

前回のgitの挙動について、今回はその内容を図で確認していく。

最初のgitコマンドを用意する

最初のgitコマンドをビルドし、`$HOME/bin-git にコピーして、コピーした場所へのPATHを通してあると仮定する。

$HOME/bin-git
$ ls $HOME/bin-git
$ cat-file  commit-tree  init-db  read-tree  show-diff  update-cache  write-tree
$ export PATH=$PATH:$HOME/bin-git
$ which cat-file
/$HOME/bin-git/cat-file

確認する内容

下記のコマンド実行によるリポジト内部の変更を逐次確認することでgitの動作を理解する。

確認するコマンド
$ init-db                  # リポジトリの初期化
$ echo "Hello" > README.md # gitで管理するファイルを作成
$ cat README.md            #  作成したファイルの内容を確認
Hello
$ update-cache README.md   # コミットするファイルをgitに登録
$ write-tree               # コミットするためにtreeオブジェクトを作成
5b884d166f3d56691ba080195ca0ceaed25f14b9
$ echo "1st commit" | commit-tree 5b884d166f3d56691ba080195ca0ceaed25f14b9 # コミット
Committing initial tree 5b884d166f3d56691ba080195ca0ceaed25f14b9
79df7b69d49cf4decaee4353d375af5390434041
$ echo "Hello, World" > README.md # ファイル内容を変更
$ show-diff                       # 変更内容を確認
README.md:  3c510aa6ed4c90af836505a9da8d9d2a0f36c5c9
--- /tmp/show_diff.fKo3Xz	2024-01-03 16:25:16.771067627 +0900
+++ README.md	2024-01-03 16:24:55.966972373 +0900
@@ -1 +1 @@
-Hello
+Hello, World
$ update-cache README.md          # コミットするファイルをgitに登録
$ write-tree                      # コミットするためにtreeオブジェクトを作成
056a16ec6554427cee5f2c087c4a3be4a6022e4b
$ echo "2nd commit" | commit-tree 056a16ec6554427cee5f2c087c4a3be4a6022e4b # コミット
Committing initial tree 056a16ec6554427cee5f2c087c4a3be4a6022e4b
ec74c2dcdcfbf5a576fc63ceece2179dc0a21d3f

リポジトリの初期化

git initに相当する処理

$ init-db
defaulting to private storage area

.dircacheディレクトリがリポジトリ用のフォルダとして作成される

gitが管理するオブジェクトは.dircacheフォルダの下のobjectsフォルダの下に配置される。多数のオブジェクトを効率よく管理するため、00から``ff`の256個のフォルダがさらに用意される。

リポジトリ構成
.dircache/
└── objects
    ├── 00
    ├── 01
    ...
    └── ff

ファイルを登録する

git addに相当する処理を行う。

ワーキングディレクトリにREADME.mdファイルを作成し、そのファイルをgitに登録する

ファイルを作成
$ echo "Hello" > README.md
$ cat README.md
Hello
ファイルを登録する
$ update-cache README.md

指定したファイルをblobオブジェクトとしてファイルに保存して、そのファイルへの参照をindexフィルに書き込む

ファイルを登録した後のリポジトリの構成

  • [add] objects/3c/510aa6ed4c90af836505a9da8d9d2a0f36c5c9
  • [add] index
リポジトリ構成
.dircache/
├── index
└── objects
    ├── 00
    ...
    ├── 3c
    │   └── 510aa6ed4c90af836505a9da8d9d2a0f36c5c9
    ...
    └── ff

登録されたREADME.mdファイルの管理

objects/3c/510aa6ed4c90af836505a9da8d9d2a0f36c5c9ファイルで管理される。

  • ファイルはzlibで圧縮されblobオブジェクトとして管理される
  • SHA1ハッシュでの管理方法
    • 3c:ディレクトリ名
    • 510aa6ed4c90af836505a9da8d9d2a0f36c5c9:ファイル名

blobオブジェクトindexファイルで管理される

  • blobオブジェクトとして保存されたREADME.mdファイルへの参照(SHA1ハッシュ)をindexに保存する
  • 登録されたREADME.mdファイルにアクセスしたい場合には3cフォルダの51...c9ファイルを確認すれば良い

スクリーンショット 2024-01-03 16.20.19.png

コミットする

git commitに相当する処理を行う

コミットはtreeオブジェクトを対象として行う。treeオブジェクトは1つ以上のblobオブジェクトへの参照を持つオブジェクトである。

treeオブジェクトを作成してcommit
$ write-tree
5b884d166f3d56691ba080195ca0ceaed25f14b9
$ echo "1st commit" | commit-tree 5b884d166f3d56691ba080195ca0ceaed25f14b9
Committing initial tree 5b884d166f3d56691ba080195ca0ceaed25f14b9
79df7b69d49cf4decaee4353d375af5390434041

treeオブジェクトを作成し、そのtreeオブジェクトを参照するcommitオブジェクトを作成する。「コミットする」とは、commitオブジェクトを作成することであり、コミットの内容はcommitオブジェクトが参照するtreeオブジェクトが参照するblobオブジェクト一覧である。

ファイルをコミットした後のリポジトリの構成

  • [add] objects/5b/884d166f3d56691ba080195ca0ceaed25f14b9
  • [add] objects/79/df7b69d49cf4decaee4353d375af5390434041
ディレクトリ構成
.dircache/
├── index
└── objects
    ├── 00
    ...
    ├── 3c
    │   └── 510aa6ed4c90af836505a9da8d9d2a0f36c5c9
    ...
    ├── 5b
    │   └── 884d166f3d56691ba080195ca0ceaed25f14b9
    ...
    ├── 79
    │   └── df7b69d49cf4decaee4353d375af5390434041
    ...
    └── ff

スクリーンショット 2024-01-03 16.19.27.png

ファイル変更

ワーキングディレクトリのREADME.mdファイルを変更する。

$ echo "Hello, World" > README.md

変更点の確認

git diffに相当する処理を行う
登録されたファイルとワーキングディレクトリのファイルとの差分を表示する。

$ show-diff
README.md:  3c510aa6ed4c90af836505a9da8d9d2a0f36c5c9
--- /tmp/show_diff.fKo3Xz	2024-01-03 16:25:16.771067627 +0900
+++ README.md	2024-01-03 16:24:55.966972373 +0900
@@ -1 +1 @@
-Hello
+Hello, World

indexファイルに登録されたファイルとワーキングディレクトリのファイルの差分をdiffコマンドを呼び出して作成して出力する。

変更をコミット

README.mdファイルの修正をコミットする。

  • コミットするファイルをupdate-cacheコマンドで登録
  • コミットに必要なtreeオブジェクトwrite-treeで作成
  • コミット対象のtreeオブジェクトをSHA1ハッシュで指定してcommitオブジェクトを作成する
修正したコードを登録
$ update-cache README.md
$ write-tree
056a16ec6554427cee5f2c087c4a3be4a6022e4b
$ echo "2nd commit" | commit-tree 056a16ec6554427cee5f2c087c4a3be4a6022e4b
Committing initial tree 056a16ec6554427cee5f2c087c4a3be4a6022e4b
ec74c2dcdcfbf5a576fc63ceece2179dc0a21d3f
ディレクトリ構成
.dircache/
├── index
└── objects
    ├── 00
    ..
    ├── 05
    │   └── 6a16ec6554427cee5f2c087c4a3be4a6022e4b : 2nd tree オブジェクト
    ..
    ├── 3c
    │   └── 510aa6ed4c90af836505a9da8d9d2a0f36c5c9 : 最初の README.md
    ..
    ├── 5b
    │   └── 884d166f3d56691ba080195ca0ceaed25f14b9 : 1st tree オブジェクト
    ├── 5c
    ├── 5d
    ├── 5e
    ├── 5f
    │   └── 60b55715af0273fd592428a179c59299a0987f : 修正した README.md
    ├── 60
    ..
    ├── 79
    │   └── df7b69d49cf4decaee4353d375af5390434041 : 1st commit オブジェクト
    ..
    ├── ec
    │   └── 74c2dcdcfbf5a576fc63ceece2179dc0a21d3f : 2nd commit オブジェクト
    ├── ed
    └── ff

修正したREADME.mdファイルのblobオブジェクトを新規に作成し、そのファイルへの参照をindexファイルに保存する。indexファイルはupdate-cacheを呼び出す毎に更新されるため、前回登録したファイルへの参照は消える。

スクリーンショット 2024-01-03 17.10.55.png

次回

次回は複数のファイルやディレクトリを対象にコミットした場合や、コミットからのリストアについて動作を確認していく。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0