在版本库中.git下有一个index文件,加上git status或者git status -s命令来完成
1.git clone一个仓库
新增一个test.txt实验文件
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
此时查看.git/index文件
jagent@ubuntu:~/xin/mytest$ ls --full-time .git/index
-rw-rw-r-- 1 jagent jagent 472 2020-11-04 13:52:22.152732161 +0800 .git/index
然后重复执行一次确认一下发现时间还是一样
此时再查看.git/index文件
rm -rf test.txt
touch tets.txt
jagent@ubuntu:~/xin/mytest$ ls --full-time .git/index
-rw-rw-r-- 1 jagent jagent 544 2020-11-04 13:53:46.389711970 +0800 .git/index
最后发现时间戳改变了,便于理解,这里相当于是文件内容不变,重新添加了文件,其实文件的时间也改了,只是git中是以.git/index时间戳来扫描工作区的。
每次工作区有变动.git/index时间戳都会更新,这样就能判断文件是否作出改动。这样比去比较文件内容更快,git这样的方式可以让工作区状态扫描更快速,这就是为什么git高效的原因之一
简洁图:
工作区 版本库
.git -------> file1--| commit |
checkout -- <file> |-----------> ˇ
test.txt -------> file2--| reset HEAD master
rm --cached | <------------ |-----file1
<--------------------- |-----------------|-----file2
... checkout HEAD<file> | |
根据图简单介绍
1.左边为工作区 右边为版本库,版本库中包含index区(暂存区) HEAD指向的是当前分支master的目录树 objects为git的对象库后续介绍
2.当工作区增删改文件执行gitadd命令时,暂存区的目录树会被更新,同时工作区修改的文件内容会被写入objects新的对象中,并对象的ID被记录在暂存区的文件索引中,目的就是为了找到新的对象,对象中包含着文件内容
3.当执行提交操作git commit时,暂存区的目录树会写到版本库中,HEAD指向的master分支会做相应的更新,简单来说master指向的目录树就是提交时的原暂存区的目录树
4.当执行git reset HEAD命令时,暂存区的目录树会被重写,HEAD指向的master分支目录树会被替换,但是工作区不受影响
5.git rm --cached <file>命令时,会直接从暂存区删除文件,工作区不会改变
6.当执行git checkout . 或者 git checkout -- <file>命令时,会用暂存区全部的文件或指定的文件替换工作区的文件,会清除工作区未添加到暂存区的改动PS:这个操作是有点危险的,容易造成文件内容丢失,通俗理解,就是将修改了的文件,但是通过gitadd未提交到暂存区的全部文件或部分文件恢复当版本库的状态
7.当执行git checkout HEAD .或 git checkout HEAD <file>命令时,会HEAD指向的master分支的全部或部门文件替换暂存区和工作区中的文件。S:这个操作是非常危险的,容易造成文件内容丢失更严重,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。通俗的将 就是恢复到git clone下来的状态