git暂存区[重要]

x33g5p2x  于2021-12-30 转载在 其他  
字(1.7k)|赞(0)|评价(0)|浏览(124)

本篇来讨论git的核心,暂存区。首先上一张图。

左侧是工作区,也就是我们本地电脑上的文件,中间的Index就是我们讨论的暂存区,右侧是HEAD。HEAD是一个头指针,我会在下一篇博客中讨论HEAD,此处你先理解为HEAD就是git版本库。

上面的这张图,非常非常地重要,如果我下面讨论的东西你有不明白的,这张图可能都会给你答案。

其实,git的绝大部分的操作都是在将文件在工作区、暂存区和版本库中移来移去,就拿上一篇博客中使用的git addgit commit来说吧,git add是把文件从工作区复制到暂存区,git commit又把文件从暂存区复制到或提交到了版本库。

下面通过一些简单的场景,把上面的命令都串一遍。
首先,通过git init命令初始化一个空的版本库,然后添加两个新的文件,分别是a.txt和b.txt。此时,工作区有两个文件,暂存区没有文件,版本库也没有文件。

#git add

git add a.txt b.txt

上面的命令将a.txt和b.txt文件从工作区复制到了暂存区。这时三个区域的目录结构是这样的

  • 工作区:a.txt , b.txt
  • 暂存区:a.txt , b.txt
  • 版本库:空

#git commit

git commit -m '新增了a.txt和b.txt文件'

上面的命令将暂存区的所有文件复制到版本库。这时三个区域的目录结构就一样了,都包含a.txt 和 b.txt。

#git checkout
git checkout --<file>命令是用暂存区的某个文件来覆盖工作区,经常用于撤销一些修改,这个命令比较危险,因为会修改工作区,且无法撤销。假设我们现在需要正在编辑a.txt,并且假设需要写两段话,写完第一段时,我们可以通过git add a.txt将a.txt复制到暂存区,这样的话,如果在写第二段时写错了,我们可以直接通过git checkout --a.txt来回到第一段完成时的样子。
也就是说,git checkout --<file>是用来使工作区回到上次操作git add时的样子。

#git checkout HEAD
git checkout HEAD <file>命令是用版本库来同时覆盖暂存区和工作区,用来彻底撤销一个修改,这个命令更加危险,因为它会同时修改工作区和暂存区,且无法撤销。还假设你想在a.txt中写两段话,写完第一段时,使用git add a.txt命令先备份到暂存区,然后接着写第二段,写着写着发现思路全错了,就可以通过git checkout HEAD a.txt将工作区和暂存区中a.txt的修改都撤销掉,回到上次操作完git commit时的样子。这个命令要慎用。

#git reset HEAD
git reset HEAD <file>命令通常用来撤销首次执行git add的操作。假设你新增了一个c.txt文件,并通过git add c.txt将此文件复制到了暂存区,但你很快就发现其实这个文件没必要提交,你可以使用git reset HEAD c.txt命令,它的本质是使用版本库来覆盖暂存区,由于版本库还没有c.txt,所以,覆盖后,暂存区也就没有了c.txt,从而实现了对git add命令的撤销。

#git rm --cached
git rm --cached <file>命令是将一个文件从暂存区删除。那么这有啥用呢?其实还是挺有用的。假设你有一个已经提交到版本库的文件,你发现这个文件其实不应该提交上去(例如配置文件,每个人的都不一样,经常造成冲突),但又不能直接删掉,假设这个文件的名字叫做user.config,你可以这么操作:

  1. 通过git rm --cached user.config命令将此文件从暂存区删除
  2. 通过修改.gitignore文件,把user.config加到文件中,使git忽略这个文件
  3. 通过git commit -m 'XXX'命令,用暂存区覆盖版本库。由于暂存区没了这个文件,覆盖后,版本库也就没了这个文件,这个文件就被这么从版本库删掉了,但是它还留在你的工作区。

是不是有点绕?没关系,多看看最上面的那张图,答案都在那里。

相关文章