git基本原理详解

1.什么是git 

 这个去google一下可以搜出一大堆,git就是一个软件管理器,不同一般的是它是分布式的,不仅有一个中心的服务器控制最新版本代码,而且每个开发者自己还有个本地仓库,所以在开发过程中都是先将代码提交到本地仓库再推送到中心服务器上的,这样的好处就是每个人都依赖于中心服务器来实现交互,但又不会被中心服务器限制,就算中心服务器挂了,也能很容易的找到最新版本的代码,而且我自己的工作依然可以顺利进行,提交到本地仓库,当中心服务器修复之后,再将自己仓库的东西推送到中心服务器。当然它还有很多的不同点,以后再来比较git和svn。

git原理总结

  Git的核心是它的对象数据库,其中保存着git的对象,其中最重要的是blob、tree和commit对象,

blob对象实现了对文件内容的记录,

tree对象实现了对文件名、文件目录结构的记录,

commit对象实现了对版本提交时间、版本作者、版本序列、版本说明等附加信息的记录。这三类对象,完美实现了git的基础功能:对版本状态的记录。

Git引用是指向git对象hash键值的类似指针的文件。通过Git引用,我们可以更加方便的定位到某一版本的提交。Git分支、tags等功能都是基于Git引用实现的。

如何理解git的快照

什么是快照
In computer systems, a snapshot is the state of a system at a particular point in time.
本人觉得快照并没含有’速度快’的意思。快照应该理解为整个系统或者应用在某个时刻的状态记录。想象一下,给一张桌子拍一张照片,纪录了桌子上所有物品的位置、状态,这样就可以称之为快照了。 

我们不必存储所有的物品,只需存储这个照片就可以了,下一次想恢复以前的状态的时候,只需要翻出当时的那张照片,再把物品按照那张照片里的位置摆放一下就OK了。 

例如,假定在A时刻,你的git工作空间分别有file1和file2,到B时刻的时候,你对file1进行了修改。
随后,在你准备进行一次commit之前,git就已经准备好快照了,这个快照记录了当前工作空间中指向未修改文件file2的指针和已经修改的file1数据(即当前时刻工作空间的文件数据状态)。因此,commit的时候,就等同于保存了一次快照。

快照怎么进行

git会读取当前工作空间的所有数据,进行数据预存,再重新调整。它会和上一次的快照版本的内容进行比较,对于没有改变的文件数据,git会把当前预存中冗余文件的数据去除掉,改为保留指向上一个版本中该文件数据的指针,对于有差异的文件数据就会保留下来,最终再把数据完整保存下来,这才算是执行了一次快照。

git和CVS,、Subversion等的区别

两者的差异在于对待保存数据的方式。前者是记录和组装一系列快照流的微型系统,关心文件数据的整体是否发生变化。每次commit的时候保存一次快照,而每个快照都包含了完整的数据;后者则关心文件内容的具体差异。第一次保存了完整的数据,往后每次保存的都不是完整的数据,只会记录基于之前的版本和现在两者的变化信息,对于此外没有变化的都不会去记录。

 2.自己的git仓库 

 我们要进行开发,提交代码和中心服务器进行交互,首先我们要有自己的一个开发基地,也就是我们自己的git仓库。拥有自己的git仓库的方式有两种,一就是在自己已有的目录里初始化自己的git仓库然后和中心服务器建立连接,更新最新代码到自己的git仓库。二就是将一个已经存在的项目克隆到自己的目录成为自己的git仓库。 

   执行git init命令,就会创建并初始化git仓库,这个时候在该目录下会产生一个.git的隐藏文件夹,而该目录就是你的工作目录,你的一切行为都是在这个目录里,而这个.git文件夹就是你的本地仓库,当你进行了一些文件操作之后,认为可以提交了那么首先你就是提交到本地仓库也就是这个.git中,然后再推送到中心服务器。或者直接克隆一个仓库到本地作为git仓库,也是一样的。当你进入到这个.git目录中,会发现里面还有很多的子目录和文件,有的是很重要的,这里说几个:

config文件,这是你项目的配置文件,里面有中心服务器的信息和分支信息,

HEAD文件指向当前的分支,

index文件是暂存区的相关信息,

logs目录中都是相关操作产生的日志,这个很重要,因为日志是我们操作的唯一证据,我们本地的版本控制也靠它,

objects目录里面存储的就是所有 的数据,也就是快照,

refs目录里是存储指向数据提交对象的指针。 

 乍看之下不知道说的什么,主要是里面的很多名字不知道是什么东西,下面再来看看一些名字概念,分支和提交对象以后再讲这个涉及版本的控制,我们先看最基本的。

 3.git的分层结构

 刚开始学习git的时候,总是一头雾水,又是什么工作目录,又是什么暂存区,又是什么本地仓库,又是什么远程仓库,还尼玛快照,看的我头晕眼花的。但是只要把这几个概念弄清楚,那么最基本的开发就不是问题了。

先来看看我所理解的git的分层结构: 

       git的工作总共分四层,其中三层是在自己本地也就是前面说的git仓库,包括了工作目录,暂存区和本地仓库,工作目录就是我们执行命令git init时所在的地方,也就是我们执行一切文件操作的地方,暂存区和本地仓库都是在.git目录,因为它们只是用来存数据的。远程仓库在中心服务器,也就是我们做好工作之后推送到远程仓库,或者从远程仓库更新下来最新代码到我们的git仓库。git所存储的都是一系列的文件快照,然后git来跟踪这些文件快照,发现哪个文件快照有变化它就会提示你需要添加到暂存区或是提交到本地仓库来保证你的工作目录是干净的。

      这个怎么理解呢,git中的文件有两种状态,一种是被跟踪的,也就是提交到本地仓库的文件,因为本地仓库要保管它们当然得跟踪他们,对它们负责,还有一种就是未被跟踪的。那么当我们添加新的文件时,它不是被跟踪的,因为本地仓库里面没有这个文件,它是外来的,本地仓库目前还不需要对他们负责。但是如果是对仓库已经存在的文件进行修改,那么这些文件就是被跟踪的文件,就可以通过git status查看他们的状态来进行相应的操作。当然我们也可以生成一个.gitignore文件,里面指定要忽略的文件类型,然后这些文件就不会被跟踪,不管怎么改变它们,git status都不会提示你需要做什么操作的。 

        所以当我们在工作目录中进行文件操作后,要先添加到暂存区,然后再将暂存区中刚添加的文件快照提交到本地仓库,然后再将本地仓库的最新版本文件快照推送到远程仓库。这个文件快照其实就是各个文件的在被添加到暂存区时的状态,就和照相一样的,留下每个不同时刻的快照,方便以后查询,而git存储的就是这些一系列的快照。说到这个快照就要说说git的对象了。

4.git的对象 

      从根本上讲,git是一套内容寻址的文件系统,它存储的也是key-value键值对,然后根据key值来查找value的,说到寻址就会想到指针吧,不错,git也是根据指针来寻址的,这些指针就存储在git的对象中。git一共有3种对象,commit对象,tree对象和blob对象。下面便是这3个对象: 

 这个blob对象对应的就是文件快照中那些发生变化的文件内容,

而tree对象则记录了文件快照中各个目录和文件的结构关系,它指向了被跟踪的快照,

commit对象则记录了每次提交到本地仓库的文件快照,

从上图看出其中有两个指针,一个指向tree对象,一个则指向上一个commit对象。这个怎么理解呢,怎么还有上一个commit对象,在开发过程中,我们会提交很多次文件快照,那么第一次提交的内容会用一个commit来记录,这个commit没有指针指向上一个commit对象,因为没有上一个commit,它是第一个,当第二次提交时,又会有另外一个commit对象来记录,那么这次commit对象中就会有一个指针指向上一次提交后的commit对象,经过很多次提交后就会有很多的commit对象,它们组成了一个链表,当我们要恢复哪个版本的时候,只要找到这个commit对象就能恢复那个版本的文件不是吗。而我们所谓的HEAD对象其实就指向最近一个提交的commit对象,也就是最后一个commit对象。 

5.git的基本操作

      上面说了这么多东西,也该看看基本操作了,基本上的操作无非是文件的增删改和版本的提交更新回溯。当把上面的内容弄清楚之后,这些基本操作根本就是小草一碟:

     上面列出了基本上能用到的所有命令,当然还没涉及到分支,这个概念后面再说,基本的用法google一下一大堆,这里不用多说,还有就是要经常用到git status这个命令,它可以指引你该干嘛干嘛,确定你的工作目录是否干净。干净的意思就是和暂存区还有本地仓库保持一致。还有一个命令也是经常用到的,那就是git log,这个命令会列出你的操作产生的日志,有很多的信息,还有提交后的commit对象的id,这个checkout版本的时候用处很大 

6.学习感受 

      以前在用svn的时候,基本两条命令就可以搞定,svn up,svn ci,svn di更新,提交和比较,就知道哦svn up是将服务器的代码更新到本地,哦svn ci是将本地代码提交到服务器,有冲突哦svn di解决冲突了再提交。根本不知道其结构式怎样,这些会导致什么结果,用起来总是小心翼翼,生怕把服务器搞挂了。学习就是要知其所以然,用起来才会顺手,基本原理弄懂之后,操作这些就是相关命令多用用自然搞定。我也是个git初学者。

推荐一篇文章,这篇文章很深入的分析了git内部原理,以至于我都没看懂多少,惭愧:www.open-open.com/lib/view/op… git分支后面再讲。

猜你喜欢

转载自juejin.im/post/6950513640550187044
今日推荐