一、什么是Git

答:Git是一个分布式版本控制软件。另外提一句,它的开发者就是大名鼎鼎的Linux之父Linus。

版本控制,顾名思义,是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的技术。(“后悔药”)

分布式,是一种版本控制的方式,有一个中心的服务器控制最新版本代码,每个开发者自己还有个本地仓库,在开发过程中先将代码提交到本地仓库再推送到中心服务器上。

也就是说,Git可以帮助我们完成这几件事:

回到过去

改变历史

古今对比

并行开发

谁动了我的代码

除了Git外,常见的版本控制软件还有SVN等

二、Git基本原理

Git的基本操作有很多,如果不理解其中的原理只是靠死记硬背,那肯定会事倍功半,所以,我建议第一步我们来学习下它的基本原理(亲身体会啊/哭,以前学过好几次Git,但过一段一时间不用就忘得差不多了,回头想想原来学的总是一知半解)。

我们先来想一个问题:Git为什么能知道我们以前的代码,为什么能“回到过去”,答案就是因为Git把我们每一次修改提交的代码以及状态都保存了下来,而展示给我们的只有当前一个版本。看下面这张图:



每次提交或保存当前项目状态,Git都会生成一个当前所有文件状态的快照,并存储一个对该快照的引用;而且文件没有发生变化时,Git不会重复保存快照,而只是链接到之前的标识文件。

说到这,可能还点不明白,别急,我们接下来看看快照到底存储了哪些东西。

快照存储不是一个个代码源文件,而是四种对象,几乎所有的Git操作都是在这四种对象上完成的,这四种对象是:

  • “blob”:一个“blob”通常用来存储文件的内容。一个“blob”对象就是一块二进制数据,它没有指向任何东西或有任何其它属性,甚至没有文件名。因为“blob”对象内容全部都是数据,所以如若两个文件在一个目录树或是一个版本仓库中有同样的数据内容,那么它们将会共享同一个“blob”对象。“blob”对象和其所对应的文件所在路径、文件名是否改被更改都完全没有关系。
  • “tree”:像一个目录,管理一些“tree”对象或是“blob”对象。它有一串指向“blob”对象或是其它“tree”对象的指针,一般用来表示内容之间的目录层次关系(就像文件和子目录)。
  • “commit”:“commit”对象指向一个“tree对象”,并且带有相关的描述信息,标记项目某一个特定时间点的状态。它包括一些关于时间点的元数据,如时间戳、最近一次提交的作者、指向上次提交的指针等等。
  • “tag”:一个“tag”对象包括一个对象名(SHA1签名)、对象类型、标签名、标签创建人的名字(“tagger”), 还有一条可能包含有签名(signature)的消息。

这些对象的关系可以用下图来理解:



所有的对象通过commit对象联系起来,每一次commit对象中又都会指向上一次提交后的commit对象,所以如果我们什么时候想回退版本,只需要找到相应的commit对象即可。而我们所谓的HEAD对象其实就指向最近一个提交的commit对象,也就是最后一个commit对象。

例如我们有一个项目,如果我们把它提交(commit)到一个Git仓库中, 在Git中“blob”、“commit”和“tree”对象的关系看起来会如下图:



可以看到: 每个目录都创建了“tree”对象, 每个文件都创建了一个对应的“blob”对象。最后有一个“commit”对象来指向根“tree”对象,这样我们就可以追踪项目每一项提交内容。

另外,这些对象的命名也很有讲究:在Git里随处可见一种“40个字符”的字符串(例如 6ff87c4664981e4397625791c8ea3bbb5f2279a3)。由于Git中每一个“对象名”都是对“对象”内容做SHA1(SHA1是一种密码学的哈希算法)哈希计算得来的,所以对于内容不同的对象,会有不同的SHA1哈希值。这样就意味着两个不同内容的对象不可能有相同的“对象名”。

这样,一次快照就是将有关的对象,即一组组由对象名和对象内容组成的的键值对存储下来。所以Git才会有那么好的“记忆力”。

三、Git用户交互

第二部分已经介绍了Git的基本原理,但只是涉及到Git自己内部存储,没说用户该怎么操作,所以为了能正常输入和输出,与用户交互,Git做了这样几件事。

说到这,我又想提一个常见的词API,API就是Application Programming Interface(应用程序接口),《JavascriptDOM编程艺术》书里提到“简单地说,API就是一组已经得到有关各方共同认可的基本约定”,说实在地我觉得这说的一点也不简单,书里这样说可能是想定义得更加广泛,但我的理解是从小地说API就像一个封装完成的函数,你给它一个输入,它给你一个输出,从大地说API就是一个程序,也是输入与输出,区别就在于规模的不同,结合到本文的内容,Git也像是一个API,输入命令,操作数据。好了我不说了,感觉自己着迷了,看什么都像API 。\笑哭

回到正文,Git为了与交互,做了什么事呢?

答案在下面的图里:

在Git,文件可能有三种状态:已提交(committed),已修改(modified),暂存(staged):

  • 已提交(commited),说明数据已经存储在本地数据库;
  • 已修改(modified),说明数据被修改,但是尚未存储到本地数据库;
  • 暂存(staged),说明已标记将一个被修改的文件(当前版本)添加到待提交的快照中。

这三种状态分别对应Git项目的三大区块:Git目录,工作目录,暂存区。

  • Git 目录(repository),即Git存储项目元数据和对象数据库的地方,也就是我们克隆(clone)某项目仓库时拷贝下的内容所在地;
  • 工作目录(working directory),即从项目某版本中检出的当前所处分支,也就是从Git目录数据库中拉取的文件在本地磁盘保存所在地;
  • 暂存区(staging area),即一个文件,通常包含在Git目录中,存储下一次需提交的内容,有时,它指向我们所说的“index”索引。

所以我们的实际操作流程是:

  • 从Git目录,检出分支到工作目录
  • 在工作目录修改文件
  • 暂存文件,将其添加到待提交快照
  • 提交,将快照持久化提交到Git目录

这些结合起来,就为我们进行代码版本控制提供了充足的底层支撑,这次就先写到这里,下一篇将详细介绍Git的使用与指令。

开发工具之Git(一)的更多相关文章

  1. IDEA开发工具使用 git 创建项目、拉取分支、合并分支

    转载自:https://blog.csdn.net/qq_39470733/article/details/80366435 工作中多人使用版本控制软件协作开发,常见的应用场景归纳如下: 假设小组中有 ...

  2. 开发工具之Git(二)

    目录 四.Git安装与配置 (一)安装 (二)配置 (三)创建仓库 五.Git基本命令 六.Git分支 上一篇讲了Git的基本原理,建议没看过的同学先看看,然后这次我们来讲Git的具体操作和指令. 四 ...

  3. 开发工具之GIT

    GIT WORKFLOW this readme created on 2019.07.28 by Suarez7988 这是一遍介绍git版本控制流程的中文说明,必须通篇阅读一下 https://g ...

  4. Java,面试题,简历,Linux,大数据,常用开发工具类,API文档,电子书,各种思维导图资源,百度网盘资源,BBS论坛系统 ERP管理系统 OA办公自动化管理系统 车辆管理系统 各种后台管理系统

    Java,面试题,简历,Linux,大数据,常用开发工具类,API文档,电子书,各种思维导图资源,百度网盘资源BBS论坛系统 ERP管理系统 OA办公自动化管理系统 车辆管理系统 家庭理财系统 各种后 ...

  5. 如何使用IDEA开发工具中右键中的Git图形化工具

    首先,你的项目一定是git服务器上面down下来的,下面来演示如何使用IntelliJ IDEA 开发中在鼠标右键中提供的一个非常方便的图形化Git管理工具: 这里使用的IDEA开发工具的版本是 In ...

  6. 开发工具--浅谈Git

    工具|浅谈Git Git这个工具,是我一直想写文章,终于我实现了我的想法.在我开始写之前,发表一下自己的看法,git只是一个工具,既然已经认定是一个工具,那么一定具备工具这类的共同特征,请用面向对象的 ...

  7. Chrome 开发工具之Console

    前段时间看git的相关,记的笔记也大致写到了博客上,还有些因为运用不熟,或者还有一些疑惑点,暂时也不做过多纠缠,之后在实践中多运用得出结论再整理分享吧. 工欲善其事,必先利其器.要想做好前端的工作,也 ...

  8. Android 常用开发工具以及Mac常用软件

    Android 常用的开发工具记录.其中包括AndroidStudio(IDEA)插件.Mac 上好用的软件以及国内知名Android开发者博客等. Android Studio 插件 codota ...

  9. 超全的web开发工具和资源

    首页 新闻 产品 地图 动态 城市 帮助 论坛 关于 登录 注册 · 不忘初心,继续前进,环境云V2接口正式上线 · 环境云测点地图全新改版 · 祝福各位环境云用户中秋快乐!   平台信息 培训互动 ...

随机推荐

  1. day15 Pyhton学习

    迭代器 掌握for循环 实际上for循环的本质,就是将一个可迭代的变成迭代器 每一次从中取值都相当于执行了一次next 如果是迭代器,那么只能取一次值 生成器 - 本质就是迭代器 生成器函数(返回值是 ...

  2. operator bool()是什么

    operator bool()是什么 在C++中,operator TypeName()语法用来将对象转换为指定的TypeName类型,当这里TypeName为bool时,就可以直接在条件判断式里面直 ...

  3. laravel重写

    laravel location / { try_files $uri $uri/ /index.php?$query_string; } ci location / { try_files $uri ...

  4. 树莓派调试PCF8591遇到的小问题

    错误提示:bus = smbus.SMBus(1) IOError: [Errno 2] No such file or directory 提示的内容为端口没有打开即IIC端口:如图,打开IIC使能 ...

  5. CPU:Central Processing Unit

    CPU执行计算任务时都需要遵从一定的规范,程序在被执行前都需要先翻译为CPU可以理解的语言.这种规范或语言就是指令集(ISA,Instruction Set Architecture). CPU 架构 ...

  6. 输出c字母图形

    1 #include "stdio.h" 2 #include "math.h" 3 int main(void) 4 { 5 double y; 6 int ...

  7. 关于linux epoll的了解

    使用select/poll模型假设一台服务器需要支持100w的并发连接,在_FD_SETSIZE为1024时,则至少需要1k个进程 除了进程间的上下文切换的时间消耗外,从内核/用户空间,大量的无脑内存 ...

  8. 深度学习中卷积层和pooling层的输出计算公式(转)

    原文链接:https://blog.csdn.net/yepeng_xinxian/article/details/82380707 1.卷积层的输出计算公式class torch.nn.Conv2d ...

  9. Qt导入CMakeLists.txt后无法调试

    问题: Qt导入CMakeLists.txt后无法单步调试 解决方法: 在CMakeLists.txt后加入一句: SET(CMAKE_BUILD_TYPE DEBUG)

  10. 美区Apple ID账号共享

    前言 前几天我已经分享了日区的账号,今天我来分享一下美区的账号.说到这个美区的账号,满满的记忆呀!这是我第一个公众号时创建的外服账号,里面的软件比较多,原本想整理一下自己购买了哪些软件的,乍一看,已购 ...