Git add, commitをした時、中でどんな事が起こっているのか
あらすじ
いまだにファイルがどういうタイミングでリポジトリ、インデックス、ワーキングエリア間を行き来しているのかわからんので色々調べてみることに。
参考資料、サイト
やってみる
まずは、空のREADMEファイルを作ってFirst commit。
$ git init Initialized empty Git repository in /tmp/repos/.git/ $ touch README $ git add README $ git commit -m "first commit" [master (root-commit) b0d99b3] first commit 0 files changed create mode 100644 README $ git log --graph --date-order --all --date=short -C -M --pretty=format:"%h"\ %t\ %ad\ %Cblue%cn%Creset\ %Cgreen%d%Creset\ %s * b0d99b3 543b9be 2012-08-29 kk_Ataka (HEAD, master) first commit
色々確認
ゆっくり
READMEを編集してみる。
$ echo "このリポジトリはテスト用です" > README $ git status # On branch master # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: README # no changes added to commit (use "git add" and/or "git commit -a")
addしたとき
ここでREADMEファイルをadd。
$ git add README $ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: README #
再度、色々確認。
リポジトリにコミットされているREADME e69de29 の他にde7e855 というオブジェクトがステージされている。おまけに.git/objectsの下にも。
- addした時点で、gitリポジトリの中に入れ込まれている?
- リセットしても.git/objectsの下からは消えない(ただ、この状態でほったらかしておくとどこからも参照されないからいずれgcされて死ぬ?)
$ git reset HEAD README Unstaged changes after reset: M README $ git status # On branch master # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: README # no changes added to commit (use "git add" and/or "git commit -a") $ find .git/objects .git/objects/de/7e8558a365886d75f9c1ac6861693be19bdc53 .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 .git/objects/54/3b9bebdc6bd5c4b22136034a95dd097a57d3dd .git/objects/b0/d99b34f1e2497a78619de4fde08b62f2d851f7 $ git cat-file -p de7e8558 このリポジトリはテスト用です
まとめ
以上の事から
- addした時、既にリポジトリにファイルは追加されている。また、インデックスの参照先も更新されている
addした後
- commitした時、インデックスがそのまま次のコミットのツリーオブジェクトになる。そのツリーオブジェクトを取りまとめるコミットオブジェクトを作成し、tree情報とparent情報を持たせる
- で、ブランチの参照先を更新してやる