本文适合有一定的git基础的人阅读
Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念,下面我以在windows系统中进行相关的讲解。
一、工作区(Working Directory)——其实就是一个文件夹
就是你在电脑里能看到的目录,比如我在F盘下面建了一个GitRepository文件夹,使用命令为:mkdir f:\GitRepository .那么这个GitRepository文件夹其实就是一个工作区。
二、版本库(Repository)——其实就是.git隐藏文件夹
工作区有一个隐藏目录.git
,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,暂存区有时候也称之为索引区。还有Git为我们自动创建的第一个分支master
,以及指向master
的一个指针叫HEAD
。
那我们怎么去查看这个.git隐藏文件夹?因为我的事win10系统,可以在文件夹中通过“查看”勾选“隐藏的项目”既可以查看到隐藏文件夹了。
前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:比如我们添加一个tt.txt文本文件在GitRepository目录之下。这个文本文件只有一两个数字111.
[master (root-commit) 98e1592] create successfully
1 file changed, 1 insertion(+)
create mode 100644 tt.txt
第一步是用git add
把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit
提交更改,实际上就是把暂存区的所有内容提交到当前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master
分支,所以,现在,git commit
就是往master
分支上提交更改。
你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
俗话说,实践出真知。现在,我们再练习一遍,先对 tt.txt
做个修改,比如加上两行内容:
111
222
333
然后执行命令 git commit -a -m "insert successfully"
接下来,我们自己在GitRrpository这个目录下创建一个 ss.txt文本文件,并且添加一行文本 aaa,但是我们不去将这个 ss.txt文本文件add进去,这时候我们通过状态查看GitRepository下面两个文本文件的的状态:
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed) //说明ss.txt没有添加进master里面去
git commit
就可以一次性把暂存区的所有修改提交到分支(branch)。
图中我们可以看出此时 "HEAD" 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下,里面包含了创建的各种对象及内容。
当对工作区修改(或新增)的文件执行 "git add" 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
当执行 "git reset HEAD" 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
当执行 "git rm --cached <file>" 命令时,会直接从暂存区删除文件,工作区则不做出改变。
当执行 "git checkout ." 或者 "git checkout -- <file>" 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。
当执行 "git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。