那么,简单地说,Git 究竟是怎样的一个系统呢?请注意,接下来的内容非常重要,若是理解了 Git 的思想和基本工作原理,用起来就会知其所以然,游刃有余。

在开始学习 Git 的时候,请不要尝试把各种概念和其他版本控制系统(诸如 Subversion 和 Perforce 等)相比拟,否则容易混淆每个操作的实际意义。Git 在保存和处理各种信息的时候,虽然操作起来的命令形式非常相近,但它与其他版本控制系统的做法颇为不同。理解这些差异将有助于你准确地使用 Git 提供的各种工具。

直接记录快照,而非差异比较

Git 和其他版本控制系统的主要差别在于,Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。这类系统(CVS,Subversion,Perforce,Bazaar 等等)每次记录有哪些文件作了更新,以及都更新了哪些行的什么内容:

其他系统在每个版本中记录着各个文件的具体差异

Git 并不保存这些前后变化的差异数据。实际上,Git 更像是把变化的文件作快照后,记录在一个微型的文件系统中。每次提交更新时,它会纵览一遍所有文件的指纹信息并对文件作一快照,然后保存一个指向这次快照的索引。为提高性能,若文件没有变化,Git 不会再次保存,而只对上次保存的快照作一链接。Git 的工作方式就如下图所示。

Git 保存每次更新时的文件快照

这是 Git 同其他系统的重要区别。它完全颠覆了传统版本控制的套路,并对各个环节的实现方式作了新的设计。Git 更像是个小型的文件系统,但它同时还提供了许多以此为基础的超强工具,而不只是一个简单的 VCS。稍后会讨论 Git 分支管理的时候,我们会再看看这样的设计究竟会带来哪些好处。

近乎所有操作都是本地执行

在 Git 中的绝大多数操作都只需要访问本地文件和资源,不用连网。但如果用 CVCS 的话,差不多所有操作都需要连接网络。因为 Git 在本地磁盘上就保存着所有当前项目的历史更新,所以处理起来速度飞快。

举个例子,如果要浏览项目的历史更新摘要,Git 不用跑到外面的服务器上去取数据回来,而直接从本地数据库读取后展示给你看。所以任何时候你都可以马上翻阅,无需等待。如果想要看当前版本的文件和一个月前的版本之间有何差异,Git 会取出一个月前的快照和当前文件作一次差异运算,而不用请求远程服务器来做这件事,或是把老版本的文件拉到本地来作比较。

用 CVCS 的话,没有网络或者断开 VPN 你就无法做任何事情。但用 Git 的话,就算你在飞机或者火车上,都可以非常愉快地频繁提交更新,等到了有网络的时候再上传到远程仓库。同样,在回家的路上,不用连接 VPN 你也可以继续工作。换作其他版本控制系统,这么做几乎不可能,抑或非常麻烦。比如 Perforce,如果不连到服务器,几乎什么都做不了(默认无法发出命令 p4 edit file 开始编辑文件,因为 Perforce 需要联网通知系统声明该文件正在被谁修订。但实际上手工修改文件权限可以绕过这个限制,只是完成后还是无法提交更新。);如果是 Subversion 或 CVS,虽然可以编辑文件,但无法提交更新,因为数据库在网络上。看上去好像这些都不是什么大问题,但实际体验过之后,你就会惊喜地发现,这其实是会带来很大不同的。

时刻保持数据完整性

在保存到 Git 之前,所有数据都要进行内容的校验和(checksum)计算,并将此结果作为数据的唯一标识和索引。换句话说,不可能在你修改了文件或目录之后,Git 一无所知。这项特性作为 Git 的设计哲学,建在整体架构的最底层。所以如果文件在传输时变得不完整,或者磁盘损坏导致文件数据缺失,Git 都能立即察觉。

Git 使用 SHA-1 算法计算数据的校验和,通过对文件的内容或目录的结构计算出一个 SHA-1 哈希值,作为指纹字符串。该字串由 40 个十六进制字符(0-9 及 a-f)组成,看起来就像是:

1 24b9da6552252987aa493b52f8696cd6d3b00373

Git 的工作完全依赖于这类指纹字串,所以你会经常看到这样的哈希值。实际上,所有保存在 Git 数据库中的东西都是用此哈希值来作索引的,而不是靠文件名。

多数操作仅添加数据

常用的 Git 操作大多仅仅是把数据添加到数据库。因为任何一种不可逆的操作,比如删除数据,都会使回退或重现历史版本变得困难重重。在别的 VCS 中,若还未提交更新,就有可能丢失或者混淆一些修改的内容,但在 Git 里,一旦提交快照之后就完全不用担心丢失数据,特别是养成定期推送到其他仓库的习惯的话。

这种高可靠性令我们的开发工作安心不少,尽管去做各种试验性的尝试好了,再怎样也不会弄丢数据。至于 Git 内部究竟是如何保存和恢复数据的,我们会在后面讨论 Git 内部原理时再作详述。

文件的三种状态

好,现在请注意,接下来要讲的概念非常重要。对于任何一个文件,在 Git 内都只有三种状态:已提交(committed),已修改(modified)和已暂存(staged)。已提交表示该文件已经被安全地保存在本地数据库中了;已修改表示修改了某个文件,但还没有提交保存;已暂存表示把已修改的文件放在下次提交时要保存的清单中。

由此我们看到 Git 管理项目时,文件流转的三个工作区域:Git 的工作目录,暂存区域,以及本地仓库。

工作目录,暂存区域,以及本地仓库

每个项目都有一个 Git 目录(如果 git clone 出来的话,就是其中 .git 的目录;如果 git clone --bare 的话,新建的目录本身就是 Git 目录。),它是 Git 用来保存元数据和对象数据库的地方。该目录非常重要,每次克隆镜像仓库的时候,实际拷贝的就是这个目录里面的数据。

从项目中取出某个版本的所有文件和目录,用以开始后续工作的叫做工作目录。这些文件实际上都是从 Git 目录中的压缩对象数据库中提取出来的,接下来就可以在工作目录中对这些文件进行编辑。

所谓的暂存区域只不过是个简单的文件,一般都放在 Git 目录中。有时候人们会把这个文件叫做索引文件,不过标准说法还是叫暂存区域。

基本的 Git 工作流程如下:

  1. 在工作目录中修改某些文件。
  2. 对修改后的文件进行快照,然后保存到暂存区域。
  3. 提交更新,将保存在暂存区域的文件快照永久转储到 Git 目录中。

所以,我们可以从文件所处的位置来判断状态:如果是 Git 目录中保存着的特定版本文件,就属于已提交状态;如果作了修改并已放入暂存区域,就属于已暂存状态;如果自上次取出后,作了修改但还没有放到暂存区域,就是已修改状态。

Git的思想和基本工作原理2的更多相关文章

  1. Git的思想和基本工作原理

    Git的思想和基本工作原理 Chapter: 开始了解Git 1. 先谈谈版本控制的一些事 2. Git诞生背后的一些故事 3. 版本控制:集中式VS分布式 4. Git的思想和基本工作原理 5. G ...

  2. 漫谈Github与开源,Git介绍以及Git的思想和基本工作原理 Git工作流程

    漫谈Github与开源 文字亮点: 为什么这些优秀的工程师会开源自己的项目? 因为开源是一种精神. 无数的软件开发者苦心积虑保护自己的代码不被破解,而还是被聪明绝顶的脚本小子破解了,但破解无数软件的脚 ...

  3. Git 思想和工作原理

    从根本上来讲,Git是一个内容寻址文件系统,并在此之上提供了一个版本控制系统的用户界面,它是一个非常强大且易用的工具,理解Git的工作原理,能够帮助我们更容易学习和使用Git. 本文不会像书籍里那样, ...

  4. 代码管理工具 --- git的学习笔记二《git的工作原理》

    通过几个问题来学习代码管理工具之git 一.git是什么?为什么要用它?使用它的好处?它与svn的区别,在Mac上,比较好用的git图形界面客户端有 git 是分布式的代码管理工具,使用它是因为,它便 ...

  5. 使用plumbing命令来深入理解git add和git commit的工作原理

    前言: plumbing命令 和 porcelain命令 git中的命令分为plumbing命令和porcelain命令: porcelain命令就是我们常用的git add,git commit等命 ...

  6. git教程1-git工作原理与初始化仓库

    一.git工作原理 1.git是版本控制器,因此管理的是版本,每一次提交commit就是新建一个版本. 2.分支:git主分支可以存放一个阶段已经完成好的版本,而修改版本则放置在次分支上. 3.融合: ...

  7. GIT的工作原理和基本命令

    1.GIT的工作原理 工作区:我们写代码的地方. 暂存区:临时存储用的. 历史区:生成历史版本的地方. 提交流程:工作区->暂存区->历史区 图示: 2.GIT的全局配置 3.创建仓库完成 ...

  8. Git 工作原理以及常用命令操作

    GIT工作原理 要了解GIT工作原理,先了解GIT的这几块区域: 工作区域划分 工作区:指的是本地工作空间,如果刚拉取下来的代码,没有修改的内容,这块区域是空白的 (modified-已修改状态) 暂 ...

  9. git文件管理与索引,深入理解工作原理

    前言 这一夜,注定是个不眠之夜,小白和cangls的对话已然进入了白热化.小白孜孜不倦的咨询关于git方面的知识,对索引越来越感兴趣.小白以前存的小电影文件可以进行版本的对比,探索哪个版本画质更好. ...

随机推荐

  1. 《java入门第一季》之面向对象面试题

    1:方法重写和方法重载的区别?方法重载能改变返回值类型吗? 方法重写: 在子类中,出现和父类中一模一样的方法声明的现象. 方法重载: 同一个类中,出现的方法名相同,参数列表不同的现象. 方法重载能改变 ...

  2. 【66】Scanner类用法详解

    Scanner是新增的一个简易文本扫描器,在 JDK 5.0之前,是没有的. public final class Scanner extends Object implements Iterator ...

  3. 集群通信组件tribes之应用程序处理入口

    Tribes为了更清晰更好地划分职责,它被设计成用IO层和应用层,IO层专心负责网络传输方面的逻辑处理,把接收到的数据往应用层传送,当然应用层发送的数据也是通过此IO层发送,数据传往应用层后必须要留一 ...

  4. 【一天一道LeetCode】#11Container With Most Water

    一天一道LeetCode系列 (一)题目 Given n non-negative integers a1, a2, -, an, where each represents a point at c ...

  5. 三消游戏FSM状态机设计图

    三消游戏FSM状态机设计图 1) 设计FSM图 2) smc配置文件 ///////////////////////////////////////////////////////////////// ...

  6. Myeclipse Db Browser使用

    1.打开Myeclipse,选择菜单栏Window-->Show View-->Other,展开MyEclipse Database,选择DB Browser,打开数据库浏览视图 2. 空 ...

  7. CIO必看:跨国集团采购部报表系统的建设经验分享

    CIO必看:跨国集团采购部报表系统的建设经验分享 引言 福耀集团是国内最具规模.技术水平最高.出口量最大的汽车玻璃生产供应商,产品"FY"商标是中国汽车玻璃行业第一个"中 ...

  8. PHP 查询脚本

    POST查询以表格传参数支持中文,GET不支持. POST查询: <?php $id=$_POST["id"];//id(中括号)为传来的参数,$id为php中的变量 //l ...

  9. 苹果新的编程语言 Swift 语言进阶(十五)--协议

    协议定义了适合某个特定任务或功能需要的方法.属性和其它需求的一个蓝图.协议本身不提供这些需求的实现,它只是描述了一个任务或功能实现的蓝图. 协议与java 语言中的接口定义类似,都是描述了一个实现可以 ...

  10. 那些年Android开发中遇到的坑

    使用静态变量来缓存数据时,不管是在Application类还是其他类,都要注意因应用重建而引发的问题. 使用DecorView作为PopupWindow的anchorView时,在华为P7中它是显示在 ...