Git之旅 - 历史起源与特点

1. Git是什么

带着这个问题,我Google了一下这个单词的含义。

是的,你没看错。原意是:蠢货、饭桶。
难道今天我们讨论的主题是这个吗,NO,No,No。是,也不全是。

:那是在这个单词没有遇到林纳斯之前。
不全是:那是在这个单词遇到林纳斯之后。

维基百科告诉我们:
Git是一个分布式版本控制软件,最初由林纳斯·托瓦兹创作,于2005年以GPL发布。最初目的是为更好地管理Linux内核开发而设计。

2. 关于名字

但凡身为开发人员,想必无人不知无人不晓这个目前最流行的代码管理软件。至于为什么是这个名字,可以从几个地方对其了解一二。
I’m an egotistical bastard, and I name all my projects after myself. First Linux, now git.
—— 林纳斯·托瓦兹自嘲地取了这个名字。
Kernel中关于Git名字的说明

1
2
(https://mirrors.edge.kernel.org/pub/software/scm/git/docs/)
git(1) Manual PageNAMEgit - the stupid content tracker

在Git源码中的README中有这么一段话

1
2
3
4
5
6
7
8
The name "git" was given by Linus Torvalds when he wrote the veryfirst version. 
He described the tool as "the stupid content tracker" and the name as (depending on your mood):
random three-letter combination that is pronounceable, and notactually used by any common UNIX command.
The fact that it is amispronunciation of "get" may or may not be relevant.- stupid.
contemptible and despicable. simple. Take your pick from thedictionary of slang.
"global information tracker": you're in a good mood, and it actuallyworks for you.
Angels sing, and a light suddenly fills the room.
"goddamn idiotic truckload of sh*t": when it breaks

3. Git历史渊源

首先,想说的是,git是一个‘悲伤的故事’所导致的产物。

自2002年开始,林纳斯·托瓦兹决定使用BitKeeper作为Linux内核主要的版本控制系统用以维护代码。因为BitKeeper为专有软件,这个决定在社群中长期遭受质疑。在Linux社群中,特别是理查德·斯托曼与自由软件基金会的成员,主张应该使用开放源代码的软件来作为Linux内核的版本控制系统。林纳斯·托瓦兹曾考虑过采用现成软件作为版本控制系统(例如Monotone),但这些软件都存在一些问题,特别是性能不佳。现成的方案,如CVS的架构,受到林纳斯·托瓦兹的批评。

2005年,安德鲁·垂鸠写了一个简单程序,可以连接BitKeeper的存储库,BitKeeper著作权拥有者拉里·麦沃伊认为安德鲁·垂鸠对BitKeeper内部使用的协议进行逆向工程,决定收回无偿使用BitKeeper的许可。Linux内核开发团队与BitMover公司进行磋商,但无法解决他们之间的歧见。林纳斯·托瓦兹决定自行开发版本控制系统替代BitKeeper,以十天的时间编写出git第一个版本。

划重点:十天时间。没错,十天时间。

大神在短短十天时间就创造了这个非凡的工具。在我看来,堪比上帝七天创造世界。不过,林纳斯创造的是一个属于程序员的世界。
什么?你连林纳斯是谁都不知道?好吧,这里放上一张我最喜欢的图片,让你见识一下大神的魅力。

(林纳斯大神的脾气就像他的代码一样牛,可我只选择看到他的代码。^_^)

4. Git周边

目前全球最大的男性同性交友网站:GitHub
很多公司使用的类似GitHub的开源系统:Gitlab
基于git的持续集成CI
……

5. 极客之王

其实,让林纳斯更被人熟知的是Linux kernel(GNU/Linux)。目前,该系统跑在全世界超过80%的服务器以及超级计算机上。我们每天都在靠着这位神一样存在的人物,赏口饭吃。他,是名副其实的极客之王。

kernel 官网:https://www.kernel.org
Git官网:https://git-scm.com
Git源码GitHub地址:https://github.com/git/git
林纳斯GitHub地址:https://github.com/torvalds

两本关于林纳斯的书籍

一部关于Linux的纪录片

http://www.bilibili.com/video/av909925/

6. 版本控制系统(VCS)

版本控制系统(version control system),是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。版本控制系统不仅可以应用于软件源代码的文本文件,而且可以对任何类型的文件进行版本控制。用的比较多的如svn,git等。

6.1 SVN vs GIT

svn:是集中化的版本控制系统, 只有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到(必须联网)这台服务器(中央服务器保存版本库元数据),取出最新的文件或者提交更新。

git:是分布式的版本控制系统,每一个终端都是一个仓库(不联网也可以,在各个客户端都保留有版本库元数据)。客户端并不只提取最新版本的文件快照,而是把原始的代码仓库完整地镜像下来。每一次的提取操作,实际上都是一次对代码仓库的完整备份(如果想测试的话,可以把 .git/object/*删除,然后再次pull。不建议实际中操作,可以测试使用)。最重量级的是创建分支so easy!

6.2 关于仓库

图中的圆柱体(数据版本库)说明了SVN代码仓库的位置,单点。 图中的圆柱体说明了GIT代码仓库的位置,多点(堪比鸣人影分身)。

6.3 关于版本

中央服务器完了,就全完了。 什么?全完?不存在的!

7. 常用的保存方式

常用的2种方式

  1. 记录文件每个版本的 快照
  2. 记录文件每个版本之间的 差异

GIT采用第一种方式。像Subversion和Perforce等版本控制系统都是记录文件每个版本之间的差异(增量保存各个版本),这就需要对比文件两版本之间的具体差异。但是GIT不关心文件两个版本之间的具体差别,而是关心文件的整体是否有改变。若文件被改变,在添加提交时就生成文件新版本的快照,而判断文件整体是否改变的方法就是用SHA-1算法计算文件的校验和。

GIT能正常工作完全信赖于这种SHA-1校验和,当一个文件的某一个版本被记录之后会生成这个版本的一个快照,但是一样要能引用到这个快照,GIT中对快照的引用,对每个版本的记录标识全是通过SHA-1校验和来实现的。

当一个文件被改变时,它的校验和一定会被改变(理论上存在两个文件校验和相同,但机率小到可以忽略不计,大概 16^40),GIT就以此判断文件是否被修改,及以记录不同版本。

在工作目录的文件可以处于不同的状态,比如说新添加了一个文件,GIT发现了这个文件,但这个文件是否要纳入GIT的版本控制还是要由我们自己决定,比如编译生成的中间文件,我们肯定不想纳入版本控制。

7.1 什么是快照

举几个日常生活中的例子

  1. 游戏 (存档点 save point)
  2. 搜索引擎 (百度快照)
  3. 数据库同步 (数据快照)

简要概括就是:记录某一刻的样子。

8. Git特点

其他版本管理系统主要差别:

① Git只关心文件数据的整体是否发生了变化,而其他多数版本管理系统则只关心文件内容的具体差异(需要增量保存差异)。
② Git并不保存文件前后变化的差异数据,更像是把变化的文件整体做一个快照,然后记录在一个微型的文件系统中。每次提交更新时,会比较这个快照。若文件没有变化,Git则只对上次保存的快照作一个链接。

Git保存的是文件的完整快照,而不是差异变化或者文件补丁。
Git每一次提交都是对项目文件的一个完整拷贝,因此你可以完全恢复到以前的任一个提交而不会发生任何区别。这里有一个问题: 如果我的项目大小是10M,那Git占用的空间是不是随着提交次数的增加线性增加呢?我提交(commit)了10次,占用空间是不是100M呢?很显然不是,Git是很智能的,如果文件没有变化,它只会保存一个指向上一个版本的文件的指针。即:对于一个特定版本的文件,Git只会保存一个副本。但可以有多个指向该文件的指针 (该指针与C语言指针不同。C语言指针内容可以变化,指针不变。但是,git的指针指向的文件发生细微变化,指针就会立即变化。)

核心特点

  1. Git底层自行维护的存储文件系统:存储的是文件快照。即整个文件内容,并保存指向该快照的索引
  2. 去中心化的分布式控制系统

9. 优缺点

优点:

  1. 适合分布式开发,强调个体
  2. 公共服务器压力和数据量不会太大,快速、灵活
  3. 任意两个开发者之间可以很快捷的解决冲突
  4. 离线工作

缺点:

  1. 学习周期较长
  2. 不符合常规思维
  3. 代码保密性差。一旦把这个库clone下来就可以获取提交的所有版本信息

归纳起来四个字:好用、难懂