虽然用了很久的git,但是也没有很好地总结下git,都是零零散散的,git其实就是用来代码管理的工具,代码管理主要完成两个功能,一个是备份,一个是代码的合并和分离。
其次android的所有源码都是一个一个git仓库,不过他是用repo来管理的,之后也把repo系统学习下。这里正好有时间可以把这个补上去,还是进入正题吧
1 git历史
- 不管怎样都要从历史开始说起,摘抄一段来自维基百科的内容:
- 自2002年开始,Linus Torvalds决定使用BitKeeper作为Linux内核主要的版本控制系统用以维护代码。因为BitKeeper为专有软件,这个决定在社区中长期遭受质疑。在Linux社区中,特别是Richard Matthew Stallman自由软件基金会的成员,主张应该使用开放源代码的软件来作为Linux核心的版本控制系统。Linus Torvalds曾考虑过采用现成软件作为版本控制系统(例如Monotone),但这些软件都存在一些问题,特别是性能不佳。现成的方案,如CVS的架构,受到Linus Torvalds的批评。
- 2005年,Andrew Tridgell写了一个简单程序,可以连接BitKeeper的存储库,BitKeeper著作权拥有者Larry McVoy认为Andrew Tridgell对BitKeeper内部使用的协议进行逆向工程,决定收回无偿使用BitKeeper的授权。Linux内核开发团队与BitMover公司进行蹉商,但无法解决他们之间的歧见。Linus Torvalds决定自行开发版本控制系统替代BitKeeper,以十天的时间,编写出第一个git版本。
2 库目录
当我们clone一份代码的时候在当前目录下会有一个.git文件夹,其实几乎所有 Git 存储和操作的内容都位于该目录下,只要删除这个文件夹,就没有git仓库了。
关于这个文件夹下的内容主要如下:
- hooks: 存储钩子的文件夹,主要是客户端或服务端钩子脚本,这个后面有机会再讲
- logs: 存储日志的文件夹
- refs: 存储指向数据 (分支) 的提交对象的指针
- objects: 存储所有数据内容
- config: 包含了项目特有的配置选项
- HEAD: 指向当前所在分支的指针文件路径,一般指向refs下的某文件
- info: 保存了一份不希望在 .gitignore 文件中管理的忽略模式 (ignored patterns) 的全局可执行文件
- index: 保存了暂存区域信息
3 Git的4种对象
先认识下SHA-1:
在Git系统中,每个Git对象都有一个特殊的ID来代表这个对象,这个特殊的ID就是我们所说的SHA-1哈希值。SHA-1哈希值是通过SHA-1算法计算出来的哈希值,对于内容不同的对象,会有不同的SHA-1哈希值。
3.1 blob
这种对象用来保存文件的内容。比如c代码或者java代码就是其源代码本身。
在Git 数据库里存储一些文本:
执行后得到输出长度为40个字符的校验和。这是个SHA-1哈希值──其值为要存储的数据加上一种头信息的校验和,先看下这个校验和的数据。
创建以该校验和前两个字符为名称的子目录,并以 (校验和) 剩下 38 个字符为文件命名 (保存至子目录下)
可以通过cat-file命令取出数据内容:
创建一个新文件,并把文件内容存储到数据库中
再向文件中写入数据:
数据库中已经将这几次的改动都保存了下来了
可以看下type类型为:blob
3.2 tree
可以理解成一个对象关系树,它管理一些tree和blob对象。
新建仓库,建立如下文件和文件夹:
查看tree对象如下所示:
由上可知lib是tree不是blob,看下lib目录下的内容:
从概念上来讲,Git 保存的数据如下所示:
3.3 commit
指向一个tree,它用来标记项目某一个特定时间点的状态。它包括以下关于时间点的元数据,如时间戳、最近一次提交的作者、指向上次提交.
commit 对象有格式很简单:指明了该时间点项目快照的顶层树对象、作者/提交者信息(从 Git 设置的 user.name 和 user.email中获得)以及当前时间戳、一个空行,以及提交注释信息。
3.4 tag
给某个提交增添一个标记。tag对象指向一个commit而不是一个 tree。它就像是一个分支引用,但是不会变化——永远指向同一个 commit,仅仅是提供一个更加友好的名字。后续命令操作中可以回味回味。
4 Git References
对于SHA-1值,在Git中,我们称之为“引用”(references 或者 refs)。你可以在 .git/refs 目录下面找到这些包含 SHA-1 值的文件。在这个项目里,这个目录还没不包含任何文件,但是包含这样一个简单的结构
可以看下图所示,差不多就明白了refs的意思了。
5 HEAD 标记
HEAD文件是一个指向你当前所在分支的引用标识符。这样的引用标识符——它看起来并不像一个普通的引用——其实并不包含 SHA-1 值,而是一个指向另外一个引用的指针。如果你看一下这个文件,通常你将会看到这样的内容:
如果你执行git checkout test,Git就会更新这个文件,看起来像这样:
基本上原理差不多了解了,当然还有很多没有细细道来,留着以后再悟好了。
之后可以看看git的一些常用命令来实际操作下吧。
参考:
git内部原理