一、前言
理解Git的思想和基本工作原理,用起来就会知其所以然,游刃有余。尽管操作命令和其他版本控制系统(如Subversion、Perforce)区别
不大,但是在保存和对待信息时还是有很大差异。
二、直接记录快照,而非差异比较
Git 和其它版本控制系统(包括 Subversion 和近似工具)的主要差别在于 Git 对待数据的方法。 概念上来区分,其它大部分系统以文件
变更列表的方式存储信息。 这类系统(CVS、Subversion、Perforce、Bazaar
等等)将它们保存的信息看作是一组基本文件和每个文件随时
间逐步累积的差异。存储每个文件与初始版本的差异
,如下图所示:
Git 不按照以上方式对待或保存数据。 反之,Git 更像是把数据看作是对小型文件系统的一组快照。 每次你提交更新,或在 Git 中保存
项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。 为了高效,如果文件没有修改,Git 不再重新存储该文件,而
是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个 快照流
。如下图所示:
这是 Git 与几乎所有其它版本控制系统的重要区别。 因此 Git 重新考虑了以前每一代版本控制系统延续下来的诸多方面。 Git 更像是一
个小型的文件系统,提供了许多以此为基础构建的超强工具,而不只是一个简单的 VCS。 稍后我们在 Git 分支讨论 Git 分支管理时,将探究
这种方式对待数据所能获得的益处。
三、近乎所有操作都是本地执行
在 Git 中的绝大多数操作都只需要访问本地文件和资源,一般不需要来自网络上其它计算机的信息。 如果你习惯于所有操作都有网络延
时开销的集中式版本控制系统,Git 在这方面会让你感到速度之神赐给了 Git 超凡的能量。 因为你在本地磁盘上就有项目的完整历史,所以
大部分操作看起来瞬间完成。
举个例子,要浏览项目的历史,Git 不需外连到服务器去获取历史,然后再显示出来——它只需直接从本地数据库中读取。 你能立即看
到项目历史。 如果想查看当前版本与一个月前的版本之间引入的修改,Git 会查找到一个月前的文件做一次本地的差异计算,而不是由远程
服务器处理或从远程服务器拉回旧版本文件再来本地处理。
这也意味着你离线或者没有 VPN 时,几乎可以进行任何操作。 如你在飞机或火车上想做些工作,你能愉快地提交,直到有网络连接时
再上传。 如你回家后 VPN 客户端不正常,你仍能工作。 使用其它系统,做到如此是不可能或很费力的。 比如,用 Perforce,你没有连接
服务器时几乎不能做什么事;用 Subversion 和 CVS,你能修改文件,但不能向数据库提交修改(因为你的本地数据库离线了)。 这看起来不
是大问题,但是你可能会惊喜地发现它带来的巨大的不同。
四、Git 保证完整性
Git 中所有数据在存储前都计算校验和,然后以校验和来引用。 这意味着不可能在 Git 不知情时更改任何文件内容或目录内容。 这个
功能建构在 Git 底层,是构成 Git 哲学不可或缺的部分。 若你在传送过程中丢失信息或损坏文件,Git 就能发现。
Git 用以计算校验和的机制叫做 SHA-1 散列(hash,哈希)。 这是一个由 40 个十六进制字符(0-9 和 a-f)组成字符串,基于 Git 中文
件的内容或目录结构计算出来。 SHA-1 哈希看起来是这样:
Git 中使用这种哈希值的情况很多,你将经常看到这种哈希值。 实际上,Git 数据库中保存的信息都是以文件内容的哈希值来索引,而
不是文件名。
五、三种状态
1、Git 有三种状态,你的文件可能处于其中之一:
已修改(modified) 表示修改了文件,但还没保存到数据库中
已暂存(staged) 表示对一个已修改文件的当前版本做了标记
已提交(committed)表示数据已经安全的保存在本地数据库中
2、Git 项目的三个工作区域的概念。工作目录、暂存区域以及 Git 仓库如下图所示:
工作目录
对项目的某个版本独立提取出来的内容,这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改暂存区域
是一个文件,保存了下次将提交的文件列表信息,也被称作‘索引’,不过一般说法还是叫暂存区域Git仓库
是 Git 用来保存项目的元数据和对象数据库的地方,从其它计算机克隆仓库时,
3、基本的 Git 工作流程如下:
- 在工作目录中修改文件。
- 暂存文件,将文件的快照放入暂存区域。
- 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。
如果 Git 目录中保存着的特定版本文件,就属于已提交状态
。 如果作了修改并已放入暂存区域,就属于已暂存状态
。 如果自上
次取出后,作了修改但还没有放到暂存区域,就是已修改状态