why

详细的文档是非常重要的,对可用性,可维护性都是极大的帮助,比如git文档,比如Rocksdb文档,比如tidb文档, 通过文档学软件要快速。写这种博客就是为了加速这个过程

git 很像文件系统,很多概念可以相互学习补充,git也算是 kv数据库

简单梳理下git功能,实际上git官方教程做的非常好,下面的总结也是官方教程的复述 教程地址https://git-scm.com/book/zh

git是怎么存储提交的

img

commit会有tree来维护对应信息,具体在blob

如果有变动,tree维护新的对应关系,commit向前移动,每次commit对应的快照就是所谓的分支起点了(都是指针节点)

img

如果创建新分支,就对应着生成新的指针节点(如果已经有分支,不能创建,因为已经有指针占位了)

img

而切换工作指针,就是把HEAD指针放到不同的分支指针上。这样也就能理解HEAD了。

fast forward

考虑一个补丁合入

git checkout -b hotfix
...
git commit ...
git checkout master
git merge hotfix

img

img

master指针转移到hotfix后面。这也就是fast-foward,直接挪到前面。还有一些概念可以见参考链接1中的内容

内部数据结构

.git目录下 主要关注HEADindex 文件,objectsrefs 目录。

  • objects 目录存储所有数据内容
  • refs 目录存储指向数据 (分支) 的提交对象的指针
  • HEAD 文件指向当前分支
  • index 文件保存了暂存区域信息

首先,git算是一个内容寻址的文件系统 ,这个高大上的名词,就是一个kv-store,hash-based,重复的数据(hash相同)地址相同。

index 更像是leveldb里的manifest。记录变更。这些东西都是相通的。

objects包含commit tree blob三种数据类型,编码算法相同,type字段不一样。内部有object数据结构,这三个是派生出来的。

refs就是指针。内部有heads目录,分支头指针。

object数据结构如下

struct object_list {
	struct object *item;
	struct object_list *next;
	const char *name;
};

struct object {
	unsigned parsed : 1;
	unsigned used : 1;
	unsigned int flags;
	unsigned char sha1[20];
	const char *type;
	struct object_list *refs;
	void *util;
};

extern int nr_objs;
extern struct object **objs;

所有对象(tree blob commit tag)都在objs这个数组中,ref添加到object的字段上。多线复杂的提交线就靠ref这个链表来串起来。

具体实现还要挨个走一遍。简单看头文件只能分析个大概。

object目录下有255个目录 00-ff 取的是 算出来的sha值的前两个

比如算出来的是47a013e660d408619d894b20806b1d5086aab03b,会存成objects/47/a013e660d408619d894b20806b1d5086aab03b

有机会走读一下代码更好。

reference

  1. 官方 git内部原理,做的十分好 (就是pro git 2)https://git-scm.com/book/zh/v1/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86

  2. git v0.99源码,基本上基础类型都有了https://git.kernel.org/pub/scm/git/git.git/tree/?h=v0.99&id=a3eb250f996bf5e12376ec88622c4ccaabf20ea8

  3. 这个博客讲了一嘴代码,有点乱,找不到源头博客 https://blog.csdn.net/varistor/article/details/10223573

  4. git原理 图文 http://marklodato.github.io/visual-git-guide/index-zh-cn.html

  5. git原理介绍,讲解.git内部结构的 https://zhuanlan.zhihu.com/p/45510461

  6. 内容寻址 文件系统https://en.wikipedia.org/wiki/Content-addressable_storage

  7. 这个博客讲的不错

    1. git对象 http://jingsam.github.io/2018/06/03/git-objects.html
    2. git 引用 http://jingsam.github.io/2018/10/12/git-reference.html
    3. git 对象hashhttp://jingsam.github.io/2018/06/10/git-hash.html
    4. git 存储 http://jingsam.github.io/2018/06/15/git-storage.html