对于会使用git的人,git add,git commit,git checkout ,git reset这些指令应该很熟悉了
我们一般使用git,修改好文件后,会用git add 文件名,git commit -m 备注这两条指令,然而他们的作用是什么呢?为什么不一条指令直接就OK了?
关于为什么需要暂存区,我们在文章末尾解答
工作区、暂存区以及版本库的概念
工作区(Working directory)
将一个文件夹通过git init 设置成一个git可以管理的文件夹时,这个文件夹里的内容就是工作区
版本库(repository)
当工作区生成后(git init),在Linux下用 ls -a 查看可以发现
除了 . / ../ 还有个 .git
这个 .git 就是版本库
注意:工作区是除了版本库之外的其他内容
暂存区(stage / index)
暂存区,叫stage 或者 index ,是用来暂时存放工作区中修改的内容;
可以理解为一个中转站
通过下图来深入理解工作区、暂存区和版本库
细心观察上图的童鞋会发现,除了工作区,暂存区,版本库,还有个东西就是object和master
什么是object
object是git对象库,是用来存储各种创建的对象以及内容
什么是master
master我们也经常用到,它是我们的主分支
当我们git init后,并不会立刻产生分支
而是我们添加了一个文件,并git add,gitcommit后
这时我们查看分支情况
便可以看到master分支了
并且悄悄告诉你,分支都存在在.git/head/refs目录下
什么是HEAD
HEAD是一个引用,引用的是当前的分支
如果当前处于master分支,那么HEAD就会指向master
如果当前切换到Dev分支或者其他分支。那么HEAd就会指向该分支
几个对三个区造成影响的指令
1、git add
当我们使用git add 指令时,就是将对应修改的文件添加到暂存区中
这时,暂存区中的目录树被更新
2、git commit
紧接着,我们使用git commit指令,便会将暂存区中做出的修改提交到版本库中
这时master指向的分支被更新
3、git reset HEAD
当使用git reset HEAD 指令时,暂存区的内容会被版本库的内容覆盖
4、git checkout --file
使用git checkout --file时,是将工作区指定修改的文件被暂存区的内容覆盖(消除所有工作区进行的改动),这个动作很危险
git checkout . 也是如此,该指令是将所有修改的文件被暂存区的内容覆盖
5、git rm --cached
使用git rm --cached file时,直接从暂存区进行文件的删除,不会影响工作区的内容
6、git checkout HEAD --file
git checkout HEAD --flie 时,会将版本库中的对应的文件内容直接替换工作区和暂存区中的该文件
这个动作也是危险的,同样git checkout HEAD . 是将所有的内容替换工作区和暂存区的文件
如何查看三个分区的区别
git diff 查看工作区和暂存区的区别
git diff --cached 查看暂存区和版本库之间的区别
git diff HEAD 查看工作区和版本库之间的区别
git status 查看当前的工作状态
为什么需要暂存区
假设一个场景:
当你自己工作时,写文件写了一半,没有commit交给版本库时
突然上司告诉你有一个Bug要紧急处理,但是完成自己的工作还需要两天时间
这时,你不能commit提交给版本库,因为你没做完,这样会影响到其他人的工作
试想:
如果没有暂存区,你修改的文件只可以立刻保存到版本库中,这样很容易对别人的工作造成影响
所以我们需要暂存区
上述场景解决步骤
1、利用git stash将自己的工作隐藏
2、新建一个bug分支来处理bug
3、处理完后,利用stash pop将隐藏的文件弹出
4、继续工作