Git 原理学习

Git 介绍

Git被 Linus 定义为 content tracker - 内容追踪者.

把一个项目建模为树型结构, 该树结构是存储着能完整还原目录和文件的一大堆内容和指向指针.

a bunch of blobs of content and a collection of pointers that can be expanded back out into a full directory of files and subdirectories.

git 适合非线性分布式开发的工作内容.

git object type ( or git object database) 存储了 git 的真实数据. 保存在 git directory 中, 每个对象用zlib进行压缩, 且用内容的 SHA-1 摘要加上数据头进行索引.

文件内容会被存储在 blob 中, 但是文件(即文件名和文件创建时间及权限)不会被存储.

Git 模型

git 目录存储对应的树型结构:
树型结构

其中, 树节点中会保存目录下的文件和目录的模式, 类型, 摘要以及名字:
树节点

那么修改的历史又保存在哪呢? 答案是保存在 commit object 里, 一个 commit 指向一个 git directory, 同时包含作者, 提交者, 信息以及之前的 parent commits.
commitmodel

通常一个 commit 会仅有一个 parent, 但是如果我们合并了两个分支, 下一个 commit 就会指向两个 parent commit.

git 的算法结构准确一点来说是有向无环图.

分支其实就是 .git/refs/heads/ 目录下的一些文件, 模型看下图, HEAD就能区分当前是指向哪个分支:
HEAD

灰色方块是指针, 有颜色圆角的是不变对象. 经过几次提交后, 可能变成:
multicommit

从上图中, 我们可以轻易从最近的一次提交中还原到最开始的提交. 并且能够完美复原当时的文件内容和目录层次, 而且仅需存储16个不变, 签名, 压缩的对象.

那么怎么来遍历?
需要 .git/refs 目录下保存各个分支或 tag 的最近一次提交. 然后就能完整遍历.
切换分支也很简单, 就是找到要切换分支的 commit, 然后恢复成当时的目录, 同时更新 HEAD 指向即可.
.git/index 文件保存着已修改但暂未提交的中间状态, 称作当前目录的缓存, 当运行 git commit 时, 新的树型结构和对象会根据 index 文件生成.

参考: https://github.com/pluralsight/git-internals-pdf/releases/download/v2.0/peepcode-git.pdf

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. Git 介绍
  2. 2. Git 模型