Previous topic

MongoEngine

Next topic

Continuation Passing Style

This Page

https://git-scm.com/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-Git-%E5%AF%B9%E8%B1%A1

cd /tmp/gitinternal
git init
[14]:
ls -al .git
total 24
drwxr-xr-x   9 chenyan  wheel  306  7 30 17:52 ./
drwxr-xr-x   3 chenyan  wheel  102  7 30 17:52 ../
-rw-r--r--   1 chenyan  wheel   23  7 30 17:52 HEAD
-rw-r--r--   1 chenyan  wheel  137  7 30 17:52 config
-rw-r--r--   1 chenyan  wheel   73  7 30 17:52 description
drwxr-xr-x  11 chenyan  wheel  374  7 30 17:52 hooks/
drwxr-xr-x   3 chenyan  wheel  102  7 30 17:52 info/
drwxr-xr-x   4 chenyan  wheel  136  7 30 17:52 objects/
drwxr-xr-x   4 chenyan  wheel  136  7 30 17:52 refs/

descriptionGitWeb使用, config文件包含项目配置, info/包含一个global exclude文件, 不在.gitignore中出现的ignore文件, hooks/包含一组hook script.

Head, index, objects/, refs组成Git的核心文件系统.

  • objects/存储所有数据内容

  • refs/存储指向数据(分支)的提交对象指针

  • HEAD指示目前被检出的分支

  • index文件保存暂存区信息.

Git本质是一个content-address file system, 也即key为address(sha1), value为数据内容的键值数据库.

[18]:
! find .git/objects
.git/objects
.git/objects/info
.git/objects/pack
[20]:
! find .git/objects -type f # 都是空文件
[21]:
! echo "foobar" | git hash-object -w --stdin
323fae03f4606ea9991df8befbb2fca795e648fa

通过hash-object命令,向git数据库写入一个”foobar”的数据, key为323fae03f4606ea9991df8befbb2fca795e648fa. -w实际写入,否则只给出计算的key值, 不实际写入. --stdin从标准输入读取内容, 否则需要给出具体输入文件地址.

通过cat-file命令, 根据key值读取文件内容, -p自动判断内容的类型.

[22]:
! find .git/objects -type f
.git/objects/32/3fae03f4606ea9991df8befbb2fca795e648fa
[24]:
cat .git/objects/32/3fae03f4606ea9991df8befbb2fca795e648fa # 具体格式是?
xK��OR0gH��OJ,�"�z
[27]:
! git cat-file -p 323fae03f4606ea9991df8befbb2fca795e648fa && git cat-file -t 323fae03f4606ea9991df8befbb2fca795e648fa
foobar
blob

以上存取的内容, 都是blob类型,即基本的数据类型. 这个过程中, 我们丢失了文件名等信息.

tree object类型用来组织文件, 存储文件名等信息. 它类似于一个简单的文件系统. 子节点是tree entry, 是一棵多叉树, 每个entry指向一个blob或者子树节点的sha1地址.

树的操作:

  • 列出分支的已提交(committed)树文件.

    • git cat-file -p master^{tree}

  • 创建暂存区.

    • git update-index --add --cacheinfo sha1hash filename

      • --add文件加入暂存区

      • --cacheinfo添加文件到git数据库,而非当前目录下

  • 根据暂存区(index)中的信息, 创建一个对应的树记录.

    • git write-tree

  • 读取树到暂存区

    • git read-tree --prefix=xxxx

  • 提交对象, 指定树的sha1

    • git commit-tree hash

    • 提交后,就可以用git log查看提交记录了.

[32]:
cd .git
/private/tmp/gitinternal/.git
[39]:
! git cat-file -p master^{tree} # 注意, 这条命令列出的都是committed的文件
100644 blob e965047ad7c57865823c7d992b1d046ea66edf78    READ.md
040000 tree e51d7608ec3542840bac94ff8cbfdd5861bd6e9c    lib
[40]:
! git cat-file -p e51d7608ec3542840bac94ff8cbfdd5861bd6e9c
100644 blob 8b137891791fe96927ad78e64b0aad7bded08bdc    tree.c
[53]:
! echo "test v1" > test.txt
[59]:
! git hash-object test.txt
915c628f360b2d8c3edbe1ac65cf575b69029b61
[60]:
! git update-index --add --cacheinfo 100644 915c628f360b2d8c3edbe1ac65cf575b69029b61 test.txt
[61]:
! git cat-file -t 915c628f360b2d8c3edbe1ac65cf575b69029b61
fatal: git cat-file: could not get object info
[62]:
! git write-tree
error: invalid object 100644 915c628f360b2d8c3edbe1ac65cf575b69029b61 for 'test.txt'
fatal: git-write-tree: error building trees
[48]:
ls
COMMIT_EDITMSG  description     info/           refs/
HEAD            hooks/          logs/           test.txt
config          index           objects/
[49]:
rm test.txt
[ ]: