认识工作区暂存区版本库

28 阅读7分钟

通过前几个视频的教学我们了解到git实际上是版本控制器,使用git可以对电脑或者服务器上所有格式的文件进行管理。然而管理需要一个前提条件,即我们需要将被管理的文件放到git仓库中进行维护,git才能追踪这些文件进行管理。接下来我们可以在git code下新建readme文件,让git来管理它。Touch一个read me。

我们在当前目录下形成了一个readme文件。接下来我想请教大家git是否可以管理readme?

image.png

请大家大胆思考,我已经提出这个问题。在当前情况下,直接给出结论,答案是不行的。有同学认为已经放入本地仓库中的文件都可以被git管理,为什么这里的readme不能被管理?接下来我要向大家明确几个概念性问题,这也是我们视频的目标。

我要向大家解释为何readme 所在gitcode目录并非本地仓库。真正的本地仓库是隐藏的.git文件,因此它才能被称为git仓库,仓库可以称为版本库。由于git实际上是版本控制系统,所以也可以称为版本库,而版本库就是我们所说的仓库。

有些同学认为既然我的readme不能被管理,那么直接将readme放到.git下面,也就是放进版本库中就可以进行被管理吗?答案是不行的,有些同学先进入.git目录下再创建一个文件,这样不被允许,而且万万不可以这么做。

我们先回到上一个目录,将点git的树状结构打印出来并贴到课件上,再次复述结论。我们不允许在点git文件下手动修改。

如果被我们误修或者误删一些东西,可能导致整个本地仓库无法使用,就会报废,因此我们不允许再点git进行手动修改。

因此,只能将我们readme文件写在gitcode的目录下,gitcode的目录称为git的工作区。你不能写在点git版本库中,只能写在工作区中。

我们已经了解到两个概念,一个是工作区,另一个是版本库。工作区是指在电脑上或者服务器上编写代码或者编写文件的目录。目前情况下,对它能否管理readme文件,答案肯定是不行的,但是肯定可以管理。然而,需要一些手段才能实现。我们的课件上为大家画了一张清晰的图,图上为我们讲解了如何将工作区的内容添加或者提交到版本库中,让版本库对这些文件进行管理。

image.png

最重要的是两步操作。首先这张图的左边是工作区,即readme所在gitcoed目录,就可以称之为工作区。另外,点git文件虽然在gitcode目录下,但是它不属于工作区。

这张图的右半部分是我们完整的版本库,即.git这个文件。我们可以看到在版本库下有两大部分是我们需要关注的内容。第一个是stage,我们将其称为暂存区,也可以叫作索引,这两种称法都可行。因此我们也可以将stage称为index。

这个版本库的左半部分有一个head指针,指针指向master分支。关于head指针和分支相关的概念,我们暂时不理解,后续会与大家讲解。我们只需要了解这一部分即可。

我们查看完这张图之后将向大家讲解如何使用git管理工作区中的文件。

首先我们需要进行的第一步操作是add操作。add操作旨在将工作区中的所有修改内容添加进版本库的暂存区中。刚才提到的工作区修改包含三部分,我们在工作区新增一个文件,也是对工作区的修改。除了新增文件之外,修改已存在的文件也是对工作区进行修改操作,以及进行删除操作。

这三个操作都算对工作区进行修改。我们在add提交并新增内容之后,系统会将修改内容保存到版本库的暂存区中。虽然版本库中已经有对应的修改内容,但是它还不算工作区内容写入真正的版本库。从暂存区的名字可以看出暂存区是暂时用于存放新增或者修改内容的区域。

我们拥有暂存区之后需要进行commit操作。

这是我们的第二步commit操作,即将暂存区的内容提交到master分支下。目前我们了解到的是提交到一个分支下。第二步commit操作后,我们才能真正意义上将所有需要管理的内容放入版本库中。完成这两步流程之后,我们才可以让他们管理readme文件。

这两步非常重要,整个流程已经向大家介绍完毕。接下来还需要向大家介绍他们到底做了什么事情。

大家之前一定很好奇git可以对文件进行版本控制的问题,然而在这张图中我们并未体现版本控制的实现方式。

接下来我将为大家回答此问题。在我们的版本库中还有一个模块,有一个部分被版本库维护着,这部分称为对象库,称为object。

Objects实际上是一个对象库,这个对象库里面存储了一堆git对象。这些git对象存储的是什么?我们可以得出一个结论,当我们在add操作新增工作区进行修改时,会将修改内容写入一个git对象中,这个git对象就会被维护到git对象库里。给大家描述一下,修改的工作区内容会写入我们对象库的一个新git对象中。

我们可以明白这个对象库中存放着各种对象,每个对象都会存储我们add第一次修改的内容。我们可以理解为在对象库中存放了很多对象,将这些对象维护起来。这些对象里面存储的都是工作区的修改,这是否表示它维护了我们文件的所有版本?

我们已经修改了一次工作区的内容,例如新增或者修改一个文件,以及删除一个文件。所有修改内容都会被存储到一个git对象中,存储和维护git对象之后实际上就能够实现对于一个文件版本的管理。

这是add,同时会在版本库里新增一个修改对象。我们向大家讲清楚之后再看暂存区,它是一个树状结构,里面存的不是一个个对象,而是一个个修改的git对象的索引。因此暂存区比较轻量级,没有一个个对象。

我们继续观看第二步commit操作。commit操作流程是将暂存区的树写到master分支下,分支呈树状结构,存的是一个目录树。目录下存在的并非对象,而是修改对象的索引,较轻量。只要我们能拿到head,就能获得master这棵树。

我们拿到这颗树结构之后可以查看某个文件的具体修改内容,之后就可以管控一个文件了。我们与大家讨论完这套方案之后,还需要对照右半部分.get目录树对照一下。

我给大家看一下我们的版本库,点git目录。首先我们看head,head对应的就是这个东西,圈出来它就是一个指针,这个指针我们就可以拿到对应的master一个分支。我们刚才也提到master分支的含义是什么,我们先不用管,只知道有第二步肯定操作之后才算真正意义上的写入了版本库就行。

接下来是对象库,在.git目录下有一个objects目录,将来所有对象都放在该目录下。最后还剩下一个暂存区,它在点git目录下,存放在一个index中。

index之所以没有被打印,是因为我们打印的是一个新建仓库的点git,并不存在暂存区。因为我们没有对仓库进行任何add操作,所以不存在index。后续在完成这套操作后,我们会带领大家查看相关内容。