您的位置:首页 > 其它

git干货系列:(二)深入学习之前先理解git暂存区

2016-03-25 00:00 429 查看
摘要: 暂存区`(stage, index)`是` Git`最重要的概念之一,理解了这个概念很多 `Git` 命令就不再那么神秘了。下面几个验证例子一开始看不懂没关系,工作区、版本库中的暂存区和版本库之间的关系图先理解先。

前言

暂存区
(stage, index)
Git
最重要的概念之一,理解了这个概念很多
Git
命令就不再那么神秘了。下面几个验证例子一开始看不懂没关系,工作区、版本库中的暂存区和版本库之间的关系图先理解先。

<!-- more -->

正文

下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系。



在这个图中,我们可以看到部分
Git
命令是如何影响工作区和暂存区
(stage, index)
的。

图中左侧为工作区,右侧为版本库。在版本库中标记为
index
的区域是暂存区
(stage, index)
,标记为
master
的是
master
分支所代表的目录树。

图中我们可以看出此时
HEAD
实际是指向
master
分支的一个“游标”。所以图示的命令中出现
HEAD
的地方可以用
master
来替换。

图中的
objects
标识的区域为
Git
的对象库,实际位于
.git/objects
目录下,我们会在后面的章节重点介绍。

当对工作区修改(或新增)的文件执行
git add
命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的
ID
被记录在暂存区的文件索引中。

当执行提交操作
(git commit)
时,暂存区的目录树写到版本库(对象库)中,
master
分支会做相应的更新。即
master
指向的目录树就是提交时暂存区的目录树。

当执行
git reset HEAD
命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。

当执行
git checkout .
或者
git checkout -- [file]
命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。

当执行
git checkout HEAD .
或者
git checkout HEAD [file]
命令时,会用
HEAD
指向的
master
分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改 动。

当执行
git rm --cached [file]
命令时,会直接从暂存区删除文件,工作区则不做出改变。

当执行
git rm file
命令时,会同时删除暂存区和工作区的文件。

当执行
rm file
命令时,只会删除工作区的文件。

下面举例子来证明以上观点

假设:
工作区:a
暂存区(index):b
HEAD:C

git diff命令结论

git diff           比较a跟b
git diff --cached  比较b跟c
git diff HEAD      比较a跟c

git reset跟 git checkout结论

git reset HEAD              c覆盖b
git checkout -- <file>      b覆盖a
git checkout HEAD <file>    c覆盖a,b

git rm命令结论

git rm          删除a跟b
git rm --cached 只删除b
rm file         只删除a

证明git diff结论

例子,默认新建一个
readme.txt
,里面输入内容
one
然后add并且
commit
一次。

1:修改
readme.txt
,新增内容
two
,这时候a内容改变了,多了
two
,而b跟c内容不变,都只有
one

执行
git diff readme.txt
查看效果



结论:如图看出,内容有修改, a跟b比较了

执行
git diff --cached readme.txt
查看效果



结论:如图看出,没有变化,因为b跟c内容一样。

执行
git diff HEAD readme.txt
查看效果



如图所示:内容有修改,a跟c比较了

2.这时候执行
git add readme.txt
,这时候a,b内容都多了two,而c内容不变,只有
one

执行
git diff readme.txt
查看效果



结论:如图看出,没有变化, 因为a跟b内容一样。

执行git diff --cached readme.txt查看效果



结论:如图看出,内容有修改,b跟c比较了

执行
git diff HEAD readme.txt
查看效果



结论:如图看出,内容有修改,a跟c比较了

3.最后使用
git commit
提交一次,这时候a,b,c内容都一样,都包含
two




结论,如图看出,没有变化,说明a,b,c内容一样

根据上面的实例再一次证明了如下观点:

git diff           比较工作区跟暂存区
git diff --cached  比较暂存区跟HEAD
git diff HEAD      比较工作区跟HEAD

证明git reset跟 git checkout结论

例子,默认新建一个
readme.txt
,里面输入内容
one
然后add并且
commit
一次,这时候a,b,c内容都是
one


1.修改
readme.txt
,新增内容
two
,执行
git add readme.txt
操作,这时候a ,b内容都多了
two
,c还是只有
one
.
执行
git reset HEAD -- readme.txt
命令后,c覆盖b,这时候b内容也变成只有
one
了,使用
git diff readme.txt
命令可以看到,有内容修改,a跟b内容不一样。



2.此时a内容有two,b和c都只有one,执行
git checkout -- readme.txt
后,b覆盖a,此时a,b,c都是one。执行
git diff readme.txt
命令可以看到,没有改变。



3.此时a,b,c都只有
one
,修改一下,添加内容
two
,执行
git add readme.txt
git commit -m "two"
.再修改一次
readme.txt
,添加内容
three
,然后会执行
git add readme.txt
,此时a跟b都包含three,而c只包含one跟two。执行
git checkout HEAD readme.txt
后,c覆盖a和b,a,b里面内容都只有one跟two。分别使用命令
git diff --cached
git diff HEAD
来查看b跟c,a跟c的比对,发现都一样。



根据上面的实例再一次证明了如下观点:

git reset HEAD              HEAD覆盖暂存区
git checkout -- <file>      暂存区覆盖工作区
git checkout HEAD <file>    HEAD覆盖暂存区和工作区


证明git rm 结论

默认新建一个
readme.txt
,里面输入内容
one
,然后使用
git add readme.txt
命令。
1.执行git rm readme.txt命令,发现文件被删除了。

2.再新建一个一个
readme.txt
,里面输入内容 one,然后使用
git add readme.txt
命令。执行
git rm --cached readme.txt
命令,发现文件内
readme.txt
还在,然后执行
git status
命令,发现是
Untracked
状态,也就是未
add
,这就说明暂存区被删除了。



根据上面的实例再一次证明了如下观点:

git rm file      会将文件从缓存区和你的硬盘中(工作区)删除
git rm --cached  只删除暂存区,不删除工作区
rm file          只删除工作区

总结

暂存区的原理需要大家重复的加深了解,基础打牢了后面学起来就轻松很多,上面几个例子都自己验证一遍,加深印象。

更多教程可以来我嘟嘟独立博客里面看到

欢迎来访:嘟嘟独立博客

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: