Git 简史
众所周知,Linux 内核开源项目有着为数众多的参与者。这么多人在世界各地为 Linux 编写代码,那Linux 的代码是如何管理的呢?事实是在 2002 年以前,世界各地的开发者把源代码通过 diff 的方式发给 Linus,然后由 Linus 本人手工合并。
你也许会问,难道那时候就没有版本控制系统吗?有是有,比如 CVS、SVN. 虽然它们免费且开源,可是用起来速度太慢,且必须联网才能使用。也有一些商用的版本控制系统,虽然比 CVS、SVN 好用,可是要收费,这和 Linux 的开源精神不符。
到了 2002 年,Linux 内核已经发展了十年有余。代码库之庞大很难再让 Linus 继续通过手工方式来管理了。于是 Linus 选择了一个商业版本控制系统 BitKeeper(由 BitMover 公司开发,属于分布式版本控制系统)。出于人道主义精神,BitMover 公司授权 Linux 社区免费使用 BitKeeper.
2005 年,BitMover 公司同 Linux 内核开源社区的合作关系结束,他们收回了 Linux 内核社区
免费使用 BitKeeper 的权力。这可怎么办呢?自己动手,丰衣足食。Linus 决定自行开发版本控制系统。仅用十天的时间,他就编写出了 git 的第一个版本(大神就是大神啊)。一个月以后,Linux 内核的源码已经由 git 管理了!
Git 的特点
直接记录快照,而非差异比较
git 和其它版本控制系统(包括 Subversion 和近似工具)的主要差别在于 git 对待数据的方法。其它系统(比如 CVS、Subversion、Perforce、Bazaar 等等)将它们保存的信息看作是一组基本文件和每个文件随时间逐步累积的差异。如下图所示:
但是 git 不按照以上方式对待或保存数据。 反之,git 更像是把数据看作是对小型文件系统的一组快照。 每次你提交更新,git 都会对当时的全部文件制作一个快照并保存这个快照的索引。 为了高效,如果文件没有修改,git 不再重新存储该文件,而是用一个链接指向之前存储的文件。
git 对待数据更像是一个 快照流。
(下图中虚线表示之前存储过,所以不重复存储。)
近乎所有操作都是本地执行
在 git 中的绝大多数操作都只需要访问本地文件和资源。比起所有操作都有网络延时开销的集中式版本控制系统,Git 在这方面会让你感到“迅雷不及掩耳盗铃儿响叮当”。 因为你在本地磁盘上就有项目的完整历史,所以大部分操作看起来瞬间完成。
这也意味着在断网环境下,几乎可以进行任何操作。 比如你在飞机上对代码做了一些修改,你能愉快地提交,直到有网络连接时再上传。 换做用 Subversion 或 CVS,你只能修改文件,但不能向数据库提交修改(因为你没网)。
保证完整性
git 中所有数据在存储前都计算校验和,然后以校验和来引用。 这意味着不可能在 git 不知情的情况下更改任何文件目录。若你在传送过程中丢失信息或损坏文件,Git 就能发现。
git 用以计算校验和的机制叫做 SHA-1 散列。 这是一个由 40 个十六进制字符组成的字符串,基于 git 中文件的内容或目录结构计算出来。 SHA-1 哈希看起来是这样的:
24b9da6552252987aa493b52f8696cd6d3b00373
git 中使用这种哈希值的情况很多。实际上,git 数据库中保存的信息都是以文件内容的哈希值来索引,而不是文件名,也不是 Subversion 那样连续的版本号。
一般只添加数据
你执行的 git 操作,几乎只往 git 数据库中增加数据。 很难让 git 执行任何不可逆操作,或者让它以任何方式清除数据。 同别的 VCS 一样,未提交更新时有可能丢失或弄乱修改的内容;但是一旦你提交快照到 git 中,就难以再丢失数据。如果你还定期把数据推送到其他仓库,那么你的数据就更难弄丢了。
参考资料
[1] https://git-scm.com/book/zh/v2/起步-Git-基础
[2] https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000