Skip to content

Instantly share code, notes, and snippets.

@yoichi
Last active May 16, 2020 05:29
Show Gist options
  • Save yoichi/4c60f75280c148ecd0d4383b3d705887 to your computer and use it in GitHub Desktop.
Save yoichi/4c60f75280c148ecd0d4383b3d705887 to your computer and use it in GitHub Desktop.
# Gitのデータ構造についての入門演習
# 履歴管理について
# 三種類のGitオブジェクト commit, tree, blobが現れます。
mkdir git-test-repository
cd $_
git init
ls .git
find .git/objects -type f
# まだなにもない
git commit --allow-empty -m "first commit"
GIT_PAGER= git log --oneline --pretty=tformat:"%H %s"
find .git/objects -type f
find .git/objects -type f | xargs ls -tr
PATTERN='s/\.git\/objects\/\(..\)\/\(.*\)/\1\2/p'
find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN}
# 一つ目は 4b825dc642cb6eb9a060e54bf8d69288fbee4904 で、二つ目は環境によって違う値。
for i in $(find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN}); do echo -n "$i "; git cat-file -t $i; done
find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN} | tail -1
find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN} | tail -1 | xargs git cat-file -p
# commit から tree への参照が見れる。
git commit --allow-empty -m "second commit"
for i in $(find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN}); do echo -n "$i "; git cat-file -t $i; done
find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN} | tail -1
find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN} | tail -1 | xargs git cat-file -p
# commit から最初と同じ tree への参照、最初のcommitへの参照(as parent)
touch readme.txt
git add $_
for i in $(find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN}); do echo -n "$i "; git cat-file -t $i; done
# blob が増えてる
git commit -m "third commit with a file"
for i in $(find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN}); do echo -n "$i "; git cat-file -t $i; done
# tree, commit が増えてる
find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN} | tail -1
find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN} | tail -1 | xargs git cat-file -p
# commit から新しいtreeへの参照、一つ前のcommitへの参照(as parent)
find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN} | tail -2 | head -1
find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN} | tail -2 | head -1 | xargs git cat-file -p
# tree からblobへの参照
echo hoge > xxx
echo hoge > yyy
git add xxx yyy
git commit -m "fourth commit adds two file with same contents"
for i in $(find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN}); do echo -n "$i "; git cat-file -t $i; done
# blobx1, treex1, commitx1 が追加されてる。
find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN} | tail -2 | head -1
find .git/objects -type f | xargs ls -tr | sed -n ${PATTERN} | tail -2 | head -1 | xargs git cat-file -p
# treeに、先ほどのreadme.txtに加えてxxx,yyyが入ってる。xxx,yyy は同じ値 "2262de0c121f22df8e78f5a37d6e114fd322c0b0"
# gitのオブジェクト管理でわかったこと
# * commit は手前のコミットの参照をもつ
# * commit はtreeの参照をもつ
# * treeはblobへの参照をもつ
#
# * ファイル毎の履歴は管理していない
# * ファイル毎の履歴は、算出するもの
# * 変更差分も管理していない。算出するもの
# * 空間的、時間的に別の場所にある、同じ内容のファイルは区別できない
# 次にブランチについてみる。
# refs = references = 参照
ls .git/refs/heads
cat .git/refs/heads/master
# 最新のcommitの値
git commit --allow-empty -m "add empty commit"
GIT_PAGER= git log --oneline --pretty=tformat:"%H %s"
cat .git/refs/heads/master
# 最新のcommitの値に更新されてる
# gitのブランチについてわかったこと
# * branchは単なるラベル
# さらに学ぶには
# https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Git%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88
# https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Git%E3%81%AE%E5%8F%82%E7%85%A7
@yoichi
Copy link
Author

yoichi commented May 16, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment