简介
前两篇分别介绍Git版本控制系统和Git仓库的一些知识,从本章起将正式深入Git的使用;
在第一篇文章《Git系列--初识》中提到了文件状态的几种类型,除了已提交
状态之外,Git工作目录下不外乎就两种文件状态:已跟踪或未跟踪。
- 已跟踪:是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后,它们的状态可能处于未修改,已修改或已放入暂存区。初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态。
- 未跟踪:工作目录中除已跟踪文件以外的所有其它文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有放入暂存区。
从上图中可以看出无论是Untracked或Modified状态的文件最终都需要转换成Staged状态的文件才能被Git管理,一般称Staged状态的文件为存入暂存区的文件。
status
在正式使用add
命令之前,在这里先引入status
命令,其作用为检查当前文件状态;一般的,Git工作目录下的文件除上述介绍的几种文件状态之外,还有一种特殊的状态,即未更改状态--代表所有已跟踪文件在上次提交后都未被更改过。
语法为:git status
add
add
命令在Git版本控制中其含义是将所有Untracked和Unstaged的文件放入暂存区,暂存区的文件即可被Git跟踪管理的文件。
初级使用
一般的,使用git add
命令开始追踪一个文件,其语法为:git add [<options>] [--] <pathspec>...
(options可通过git add -h
查看,亦可查阅add)
所以如下实例:
➜ test git:(master) ✗ echo "test" > test.txt
➜ test git:(master) ✗ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
test.txt
nothing added to commit but untracked files present (use "git add" to track)
➜ test git:(master) ✗ git add test.txt (亦可为 git add . 为添加当前目录所有未跟踪或未暂存文件)
➜ test git:(master) ✗ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: test.txt
上述实例中当创建一个新文件test.txt
时,使用git status
命令查看,Git会提示Untracked files:(use "git add <file>..." to include in what will be committed)
;而当执行add操作后,会提示Changes to be committed:(use "git rm --cached <file>..." to unstage)
,可使用git rm --cached
命令将该文件移除暂存区;所以读者可勤用git status
命令,Git会友好的提示一些命令。
再次修改文件test.txt使用git status
查看发现修改已暂存的文件出现modified状态的文件,根据git status
提示,若需要应用此次修改则使用git add
,若不应用则使用git checkout --
➜ test git:(master) ✗ echo "test11" > test.txt
➜ test git:(master) ✗ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: test.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: test.txt
➜ test git:(master) ✗ git add .
➜ test git:(master) ✗ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: test.txt
高级使用
前文中使用git add
命令可将文件放入暂存区进行追踪,那么Git还提供了一套高级命令来完成git add
操作;
Git是一个内容寻址文件系统,其核心部分是一个简单的键值对数据库(key-value data store)。它会为每一个暂存区的文件使用SHA-1 哈希算法计算校验和,生成一个blob对象。你可以向该数据库插入任意类型的内容,它会返回一个键值,通过该键值可以在任意时刻再次检索(retrieve)该内容。 可以通过底层命令 hash-object 来演示上述效果——该命令可将任意数据保存于 .git 目录,并返回相应的键值。
➜ test git:(master) ✗ ls
test.txt
➜ test git:(master) ✗ git hash-object -w test.txt
cb19826acbc17d65e6b492abf2b5b10930c184f3
➜ test git:(master) ✗ git cat-file -p cb19826acbc17d65e6b492abf2b5b10930c184f3
test11
➜ test git:(master) ✗ git cat-file -t cb19826acbc17d65e6b492abf2b5b10930c184f3
blob
➜ test git:(master) ✗ git update-index --add --cacheinfo 100644 cb19826acbc17d65e6b492abf2b5b10930c184f3 test.txt
➜ test git:(master) ✗ git st
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: test.txt
- git hash-object -w 数据来源(stdin或文件) :
输出长度为 40 个字符的校验和(一个将待存储的数据外加一个头部信息(header)一起做 SHA-1 校验运算而得的校验和) - git cat-file -p SHA-1 :
输出校验值对应的内容,-p是判断其值并显示其内容 , -t为输出该hash的类型,取值有blob,tree,commit - git update-index --add --cacheinfo 文件模式 SHA-1 文件名 :
必须为上述命令指定 --add 选项,因为此前该文件并不在暂存区中;同样必需的还有 --cacheinfo 选项,因为将要添加的文件位于 Git 数据库中,而不是位于当前目录下。
文件模式:- 100644:普通文件
- 100755:可执行文件
- 120000:符号链接
- 三种模式即是 Git 文件(即数据对象)的所有合法模式(当然,还有其他一些模式,但用于目录项和子模块)。
此时可查看.git目录下的objects内容(根据SHA-1的hash值存储的文件):
从上述的实例中我们再次能感受到Git其内部原理是键值对数据库(key-value data store),通过文件的hash值来定位文件的修改。
总结
git add
命令是将未暂存的文件存入暂存区,其内部原理是计算出该文件对应的hash值,并存储至objects目录下,以通过其内容来管理变更。
SHA-1 哈希算法
Git 中所有数据在存储前都计算校验和,然后以校验和来引用。
Git 用以计算校验和的机制叫做 SHA-1 散列(hash,哈希)。 这是一个由 40 个十六进制字符(0-9 和 a-f)组成字符串,基于 Git 中文件的内容或目录结构计算出来。
上一篇:Git系列--Git仓库