{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "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\n", "\n", "\n", "```\n", "cd /tmp/gitinternal\n", "git init\n", "```" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "total 24\r\n", "drwxr-xr-x 9 chenyan wheel 306 7 30 17:52 \u001b[1m\u001b[36m.\u001b[m\u001b[m/\r\n", "drwxr-xr-x 3 chenyan wheel 102 7 30 17:52 \u001b[1m\u001b[36m..\u001b[m\u001b[m/\r\n", "-rw-r--r-- 1 chenyan wheel 23 7 30 17:52 HEAD\r\n", "-rw-r--r-- 1 chenyan wheel 137 7 30 17:52 config\r\n", "-rw-r--r-- 1 chenyan wheel 73 7 30 17:52 description\r\n", "drwxr-xr-x 11 chenyan wheel 374 7 30 17:52 \u001b[1m\u001b[36mhooks\u001b[m\u001b[m/\r\n", "drwxr-xr-x 3 chenyan wheel 102 7 30 17:52 \u001b[1m\u001b[36minfo\u001b[m\u001b[m/\r\n", "drwxr-xr-x 4 chenyan wheel 136 7 30 17:52 \u001b[1m\u001b[36mobjects\u001b[m\u001b[m/\r\n", "drwxr-xr-x 4 chenyan wheel 136 7 30 17:52 \u001b[1m\u001b[36mrefs\u001b[m\u001b[m/\r\n" ] } ], "source": [ "ls -al .git" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`description`供`GitWeb`使用, `config`文件包含项目配置, `info/`包含一个global exclude文件, 不在`.gitignore`中出现的`ignore`文件, `hooks/`包含一组`hook script`.\n", "\n", "`Head`, `index`, `objects/`, `refs`组成Git的核心文件系统.\n", "\n", "- `objects/`存储所有数据内容\n", "- `refs/`存储指向数据(分支)的提交对象指针\n", "- `HEAD`指示目前被检出的分支\n", "- `index`文件保存暂存区信息.\n", "\n", "Git本质是一个content-address file system, 也即key为address(sha1), value为数据内容的键值数据库. " ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ ".git/objects\r\n", ".git/objects/info\r\n", ".git/objects/pack\r\n" ] } ], "source": [ "! find .git/objects" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "! find .git/objects -type f # 都是空文件" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "323fae03f4606ea9991df8befbb2fca795e648fa\r\n" ] } ], "source": [ "! echo \"foobar\" | git hash-object -w --stdin" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "通过`hash-object`命令,向git数据库写入一个\"foobar\"的数据, key为`323fae03f4606ea9991df8befbb2fca795e648fa`. `-w`实际写入,否则只给出计算的key值, 不实际写入. `--stdin`从标准输入读取内容, 否则需要给出具体输入文件地址.\n", "\n", "通过`cat-file`命令, 根据key值读取文件内容, `-p`自动判断内容的类型." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ ".git/objects/32/3fae03f4606ea9991df8befbb2fca795e648fa\r\n" ] } ], "source": [ "! find .git/objects -type f" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x\u0001K��OR0gH��OJ,�\u0002\u0000\"�\u0004z" ] } ], "source": [ "cat .git/objects/32/3fae03f4606ea9991df8befbb2fca795e648fa # 具体格式是?" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "foobar\r\n", "blob\r\n" ] } ], "source": [ "! git cat-file -p 323fae03f4606ea9991df8befbb2fca795e648fa && git cat-file -t 323fae03f4606ea9991df8befbb2fca795e648fa" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "以上存取的内容, 都是`blob`类型,即基本的数据类型. 这个过程中, 我们丢失了文件名等信息.\n", "\n", "`tree object`类型用来组织文件, 存储文件名等信息. 它类似于一个简单的文件系统. 子节点是`tree entry`, 是一棵多叉树, 每个entry指向一个`blob`或者子树节点的sha1地址.\n", "\n", "树的操作:\n", "\n", "- 列出分支的已提交(committed)树文件.\n", " - `git cat-file -p master^{tree}`\n", "- 创建暂存区.\n", " - `git update-index --add --cacheinfo sha1hash filename`\n", " - `--add`文件加入暂存区\n", " - `--cacheinfo`添加文件到git数据库,而非当前目录下\n", "- 根据暂存区(index)中的信息, 创建一个对应的树记录.\n", " - `git write-tree`\n", "- 读取树到暂存区\n", " - `git read-tree --prefix=xxxx`\n", "- 提交对象, 指定树的sha1\n", " - `git commit-tree hash`\n", " - 提交后,就可以用`git log`查看提交记录了." ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/private/tmp/gitinternal/.git\n" ] } ], "source": [ "cd .git" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "100644 blob e965047ad7c57865823c7d992b1d046ea66edf78\tREAD.md\r\n", "040000 tree e51d7608ec3542840bac94ff8cbfdd5861bd6e9c\tlib\r\n" ] } ], "source": [ "! git cat-file -p master^{tree} # 注意, 这条命令列出的都是committed的文件" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "100644 blob 8b137891791fe96927ad78e64b0aad7bded08bdc\ttree.c\r\n" ] } ], "source": [ "! git cat-file -p e51d7608ec3542840bac94ff8cbfdd5861bd6e9c" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [], "source": [ "! echo \"test v1\" > test.txt" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "915c628f360b2d8c3edbe1ac65cf575b69029b61\r\n" ] } ], "source": [ "! git hash-object test.txt" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [], "source": [ "! git update-index --add --cacheinfo 100644 915c628f360b2d8c3edbe1ac65cf575b69029b61 test.txt" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "fatal: git cat-file: could not get object info\r\n" ] } ], "source": [ "! git cat-file -t 915c628f360b2d8c3edbe1ac65cf575b69029b61" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "error: invalid object 100644 915c628f360b2d8c3edbe1ac65cf575b69029b61 for 'test.txt'\r\n", "fatal: git-write-tree: error building trees\r\n" ] } ], "source": [ "! git write-tree" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "COMMIT_EDITMSG description \u001b[1m\u001b[36minfo\u001b[m\u001b[m/ \u001b[1m\u001b[36mrefs\u001b[m\u001b[m/\r\n", "HEAD \u001b[1m\u001b[36mhooks\u001b[m\u001b[m/ \u001b[1m\u001b[36mlogs\u001b[m\u001b[m/ test.txt\r\n", "config index \u001b[1m\u001b[36mobjects\u001b[m\u001b[m/\r\n" ] } ], "source": [ "ls" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [], "source": [ "rm test.txt" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.2" } }, "nbformat": 4, "nbformat_minor": 2 }