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

本文不会像书籍里那样,一条条讨论checkout、branch、remote等诸如此类动词形式的高层命令和底层命令,本文主要从宏观方向传达Git的思想和工作原理,能够使初学者更加理解,更利于学习。

git

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

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

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

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

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

这是 Git 同其他系统的重要区别。它完全颠覆了传统版本控制的套路,并对各个环节的实现方式作了新的设计。Git 更像是个小型的文件系统,但它同时还提供了许多以此为基础的超强工具,而不只是一个简单的 VCS。

工作区和暂存区

Git 和其他版本控制系统的一个不同之处就是有暂存区的概念。

工作区(Working Directory)

在电脑中能看到的目录,比如我建立的gittest就是一个工作区

工作区
版本库(Repository)

工作区中的隐藏目录.git,就是Git的版本库。

工作区和版本库

Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。

回忆在我上一篇博客中提到的将文件添加到版本库的流程图:

将文件添加到版本库

通过以上两幅图不难看出,需要提交的文件经过add后先都放到暂存区index(或者叫stage)中,然后经过commit指令,一次性提交暂存区的所有修改到head。一旦提交后,暂存区清空,同时若对工作区没有做任何修改,那么工作区就是干净的(working directory clean)

文件的三种状态

对任何一个文件,在Git内都有三种状态:

  • 已提交(committed):表示该文件已经被安全的保存在本地数据库中了
  • 已修改(modified):表示修改了某个文件,但还没有提交保存
  • 已暂存(staged):表示把已修改的文件放在下次提交时要保存的清单中

文件流转图

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

我们可以从文件所处的位置来判断状态:

  • Git 目录中保存着的特定版本文件----->已提交状态
  • 作了修改并已放入暂存区域----->已暂存状态
  • 自上次取出后,作了修改但还没有放到暂存区域----->已修改状态

重要的 .git 目录

当一个新目录或已有目录执行git init时,Git会创建一个.git目录。这个目录包含了几乎所有Git存储和操作的对象。若想备份或复制一个版本库,只需把这个目录拷贝至另一处即可。对于一个全新的版本库,该目录结构如下所示:

目录结构图
  • description文件:仅供GitWeb程序使用
  • config文件:包含项目特有的配置选项
  • info目录:包含一个全局性排除(global exclude)文件,用以放置那些不希望被记录在 .gitignore文件中的忽略模式(ignored patterns)
  • hooks目录:包含客户端或服务端的钩子脚本(hook scripts)
  • HEAD文件:指示目前被检出的分支
  • index文件:保存暂存区信息
  • objects目录:存储所有数据内容
  • refs 目录:存储指向数据(分支)的提交对象的指针

关于Git底层命令和高层命令的原理讨论,很大一部分都在这个目录中,要想了解具体的原理,可以看这本书,这里仅仅列出了每部分的功能,有个大体了解。

基本的 Git 工作流程

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

分析 Git 命令

有了上述介绍,我们可以对 Git 的命令有更深的理解,这里以将文件添加到代码库为例进行分析:我们都知道需要两步,第一步add,第二步commit,但为什么要分两步呢?每一步都做了什么呢?

 

(1)git commit -a:相当于运行 git add 把所有当前目录下的文件加入暂存区域再运行 git commit
(2)git commit <file_name>:进行一次包含最后一次提交加上工作目录中文件快照的提交,并且文件被添加到暂存区域
(3)git checkout HEAD -- <file_name>:回滚到复制最后一次提交


作者:sunnyaxin
链接:http://www.jianshu.com/p/619122f8747b
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

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

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

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

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

  3. Git——基本思想和工作原理(二)

    核心知识点: 1.Git关注文件数据的整体是否发生变化,对更新的文件做一个快照,然后保存一个指向快照的索引,而不会关注文件数据的具体变化. 2.Git版本的更新几乎都发生在本地,不会因为没有网络而不能 ...

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

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

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

    那么,简单地说,Git 究竟是怎样的一个系统呢?请注意,接下来的内容非常重要,若是理解了 Git 的思想和基本工作原理,用起来就会知其所以然,游刃有余. 在开始学习 Git 的时候,请不要尝试把各种概 ...

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

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

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

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

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

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

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

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

随机推荐

  1. Python图像处理库(1)

    转自:http://www.ituring.com.cn/tupubarticle/2024 第 1 章 基本的图像操作和处理 本章讲解操作和处理图像的基础知识,将通过大量示例介绍处理图像所需的 Py ...

  2. matlab安装及使用

    matlab R2015b在ubuntu 14.04环境下的安装 挂载及运行安装程序 sudo mkidr /media/matlab mount -o loop matlab_R2015b.iso ...

  3. W3School WebService教程

    http://www.w3school.com.cn/webservices/index.asp

  4. java中常用的String方法

    1 length()字符串的长度 String a = "Hello Word!"; System.out.println(a.length); 输出的结果是字符串长度10. 2 ...

  5. file '/grub/i386-pc/normal.mod' not found.解决方案

    前言: 因为之前装的Ubuntu出了点问题,本想直接清除Ubuntu数据重新装一下,结果蹦出这么个BUG来,揪心,弄了大半天终于弄好了. 废话不多说,直接按教程走吧. GRUB启动: 在grub启动界 ...

  6. ubuntu下dpkg/apt的一些常用命令

    apt-get update 更新源(硬盘缓存的包的版本等)apt-get upgrade 更新包(更新系统中已安装的包,依据缓存包的版本更新)apt-get dist-upgrade 升级系统apt ...

  7. 《TDD》-火花

    1,规定对天才来说多余,对蠢才来说无效,只对中间这一部分有用(我至今没见到过天才,蠢才到是不少) 2,设计上顿悟的火花一闪而过,没有规律可循.良好的测试无法保证你在需要的时候灵感乍现,但是给人信心的良 ...

  8. Container With Most Water(LintCode)

    Container With Most Water Given n non-negative integers a1, a2, ..., an, where each represents a poi ...

  9. 封装boto3 api用于服务器端与AWS S3交互

    由于使用AWS的时候,需要S3来存储重要的数据. 使用Python的boto3时候,很多重要的参数设置有点繁琐. 重新写了一个类来封装操作S3的api.分享一下: https://github.com ...

  10. python 去掉换行符或者改为其他方式结尾的方法(end='')

    输入参数不换行,就是打印之后不换行,在python2.7中使用 "," >>>def test(): print 'hello', print "wor ...