运行机制
Git Mechanism | Git 运行机制
当你创建一个仓库的时候,使用
├── HEAD
├── branches
├── config
├── description
├── hooks
│ ├── pre-commit.sample
│ ├── pre-push.sample
│ └── ...
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
我们先粗略地看下各个文件目录的作用:
-
config: 这个文件包含你仓库的设置信息。例如这里会放你远程仓库的URL ,你的email 地址,你的用户名等…。每次你在控制台使用“git config…”指令时,修改的就是这里。 -
description: gitweb( 可以说是github 的前身) 用来显示仓库的描述。 -
hooks: 这是一个有意思的特性。Git 提供了一系列的脚本,你可以在git 每一个有实质意义的阶段让它们自动运行。这些脚本就是hooks ,可以在commit/rebase/pull …. 的前后运行。脚本的名字表示它什么时候被运行。例如一个有用的预推送hook 可能会测试关于保持远程仓库一致性的式样原则。 -
info-exclude: 你可以把你不想让git 处理的文件放到.gitignore 文件里。那么,exclude 文件也有同样的作用,不同的地方是它不会被共享,比如当你不想跟踪你的自定义的IDE 相关的配置文件时,即使通常情况下.gitignore 就足够了( 如果你用到了这个请在评论中告诉我) 。
commit 的流程
每一次你创建一个文件并跟踪它会发现,
- 如果这个文件没有改变,
git 仅仅只把压缩文件的名字( 就是哈希值) 放入快照。 - 如果文件发生了变化,
git 会压缩它,然后把压缩后的文件存入object 目录。最后再把压缩文件的名字( 哈希值) 放入快照。
一旦快照创建好,其本身也会被压缩并且以一个哈希值命名。那么所有的压缩对象都放在哪里呢?答案是
├── 4c
│ └── f44f1e3fe4fb7f8aa42138c324f63f5ac85828 // hash
├── 86
│ └── 550c31847e518e1927f95991c949fc14efc711 // hash
├── e6
│ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391 // hash
├── info // let's ignore that
└── pack // let's ignore that too
这就是我创建一个空文件
- 工作目录快照的哈希
- 提交的说明信息
- 提交者的信息
- 父提交的哈希值 如果我们解压缩一个提交,你自己可以看看到底是什么:
// by looking at the history you can easily find your commit hash
// you also don't have to paste the whole hash, only enough
// characters to make the hash unique
git cat-file -p 4cf44f1e3fe4fb7f8aa42138c324f63f5ac85828
这是我看到的
tree 86550c31847e518e1927f95991c949fc14efc711
author Pierre De Wulf <test@gmail.com> 1455775173 -0500
committer Pierre De Wulf <test@gmail.com> 1455775173 -0500
commit A
如你所见我们得到了所期望看到的的:快照的哈希,作者,提交信息。这里有两样东西很重要:
- 正如预料的一样,快照的哈希 “86550…” 也是一个对象并且能在
object 目录下找到。 - 因为这是我的第一个提交,所以没有父提交。 那我的快照里面到底是些什么呢?
git cat-file -p 86550c31847e518e1927f95991c949fc14efc711
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file_1.txt
到这里我们看到的最后一个对象是我们先前提到的唯一会存在于快照中的对象。它是一个
HEAD/ 标签/ 分支
那么现在你知道
cat HEAD
ref: refs/heads/master
这看起来
cat refs/heads/master
4cf44f1e3fe4fb7f8aa42138c324f63f5ac85828