关于git:深入浅出git三索引

暂存区

从 gi t的角度来看,文件的批改波及到以下三个区域:工作目录, stage区(暂存区)以及本地仓库.

当咱们对咱们的我的项目做了一些批改(新增文件,删除文件,批改文件等),咱们解决的就是咱们的工作目录.这个目录是存在于咱们电脑的文件系统上的.所有的批改都会保留在工作目录直到咱们把它们退出到暂存区(通过git add命令)。

暂存区这是对下一次提交最好的示意形式,当咱们执行git commit,git会获取暂存区中的批改,并将这些批改作为下一次的提交内容.暂存区的一个理论作用就是容许你调整你的提交,你能够向暂存区新增和删除批改直到你对你下一次的提交称心,这个时候你就能够用git commit提交你的内容了。

在提交批改后,它们就会进入.git/objects目录,在其中被保留为commit,blob以及tree objects,(参考数据模型那一篇文章)

把暂存区认为是一个存储批改的实在区域并不精确,git没有专门的stage目录来寄存这些文件的批改(blobs),git有一个名为index的文件来跟踪这三个区域的批改:工作目录,暂存区以及本地仓库。

当咱们增加批改到暂存区的时候,git会更新index文件中的信息,并且创立一个新的blob object,而后将它们放到与之前提交的记录所产生的其余blob雷同的.git/objects目录中。

index的变动

接下来咱们就通过一个失常的git流程来演示下git如何应用的index

首先在咱们的仓库外面有master以及feature两个分支,如果咱们执行上面的命令,会有三件事件产生

git checkout feature

第一,git会挪动HEAD指针来指向feature分支,为了更加便于了解,咱们只显示性能分支的最初一次提交

第二,git将获取feautre分支指向的提交内容并将其增加到索引中

咱们留神到index是一个文件而不是目录,所以git是没有往其中存储内容的,git只是存储咱们仓库中每个文件的信息而已,相似于下面这样

mtime : 上次更新工夫
file : 文件名称
wdir : 工作目录中文件版本
stage : index中文件版本
repo : 仓库中的文件版本

文件版本以校验和来标识,如果两个文件有雷同的校验和,那么它们就有一样的内容以及版本.

最初,git会将你的工作目录和HEAD指向的内容相匹配(它将应用树和blob对象从新创立我的项目目录的内容)

所以,当你应用checkout的时候,工作目录,暂存区以及仓库都是雷同的版本
咱们来看看当咱们编辑Main.java的时候会产生什么?

当初仅仅只影响了咱们的工作目录,然而咱们运行上面的命令的时候

git status

git 首先会更新index文件中Main.java的工作目录的版本

而后咱们看到Main.java在工作目录和暂存区有不同的版本

而后git会提醒咱们

On branch feature
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
modified:   Main.java
no changes added to commit (use "git add" and/or "git commit -a")

这就表明工作目录的批改不在暂存区中(那么下一次的提交就不会蕴含Main.java的批改).

所以,执行以下命令将Main.java退出到暂存区

git add Main.java

执行了下面这条命令,就又会产生两件事儿,第一,git会为Main.java创立一个blob object而后存储在.git/objects目录下,第二,会再次更新index文件

这个时候咱们再次执行命令

git status

git会发现Main.java的暂存区的版本和工作目录版本统一,然而和仓库的版本不统一

所以git就告知咱们

On branch feature
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
modified:   Main.java

证实Main.java曾经在暂存区,然而还没有提交到仓库.当初咱们就能够提交咱们的批改了

git commit -m "add some code to Main.java"

git会做上面几件事儿:

1. 新增commit object和tree object,并把它们和执行git add时创立的blob object连接起来
2. 挪动feature的指针到新的commit object
3. 更新index

好啦,当初咱们的Main.java在所有区域都有雷同的版本了.

无论执行 git add还是git commitindex文件都会变更,这也更好的证实了咱们上述模型,当然index文件中的内容必定没有那么清晰,它是一个二进制文件,如果想要查看它的内容就须要借助其余工具来实现

下面就是对于git index的原理了,当初回过头来看发现其实并不简单,然而对于咱们了解在一些在index上操作的命令(add,checkout,revert,commit,add…)却是至关重要的

参考文章

https://www.youtube.com/watch?v=xbLVvrb2-fY

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理