Git的两条学习路线
三个对象,三个区域,三个状态。
- 3 Objects:
Blob
=>Tree
=>Commit
- 3 Objects:
- 3 Areas:
Working Directory
=>Stage Index
=>History
-
本地工作区
=>暂存区
=>版本库\历史记录区
- 3 Status:
-
modified
,staged
,committed
- 已修改, 已暂存, 已提交
-
额外内容:
.git 目录结构
- hooks:
- info:
- logs:
- objects:
- refs:
- COMMIT_EDITMSG:
- config:
- description:
- FETCH_HEAD:
- HEAD:
- index:
Git 三大对象:
blob 对象
核心:就是个 hash-object 的 k-v 键值对数据库
代表: 单文件的一个版本,及内容
存放:file的hash(作为数据库的key),存压缩的内容(作为数据库的value)
作用区域:
本地工作区
- 缺陷:
- 只有blob对象的话,仅通过它们无法知道项目总体轮廓(文件间关联) (
引出 tree 对象
) - 只通过hash来确定key,数据不足,无法确定版本的先后顺序 (
引出 commit 对象
)
- 只有blob对象的话,仅通过它们无法知道项目总体轮廓(文件间关联) (
指令控制:
在工作区(且在objects目录中)创建blob对象: (-w)
$ echo "test content v1" > ./file.txt
$ git hash-object -w ./file.txt
- 通过linux管道(pipeline)指令,在工作区直接创建blob对象(不常用):
$ echo 'test content' | git hash-object -w --stdin
(–stdin = STarDand INput from command) - 仅查看对象 hash (SHA1) 值:
$ git hash-object ./file.txt
- 补充:
- (!) 特性:blob对象不像SVN那样存差异或增量数据,而是压缩后存储全部数据。每次新增一个hash,数据库都会增大。
(!) 自己修改完文件,若不输入
$ git hash-object -w ./file.txt
, Git是不会知道你版本有更新的。当然,这个功能被$ git add ./file.txt
封装了,但它还包含了其他功能,后续说明 [Link]。(x) 若想查看hash-object中的value,在linux命令中调用cat指令,如:
$ cat ./.git/objects/d6/5490dsn2ud3b2uf87f2b
该指令只能看到被压缩后的value (加密文件内容)
(√) 所以若想查看解压后(解码后)的object content,需要使用如下命令:
$ git cat-file -p d65490dsn2ud3b2uf87f2b
(√) 若想查看一个object的类型 (是blob,tree,还是commit类),则使用如下命令:
$ git cat-file -t d65490dsn2ud3b2uf87f2b
(其中hash值并不需要写全部,也可以匹配到)
tree 对象
核心:用指针来关联各个相关objects (blobs, or sub-trees) 的key (SHA-1 hash),从而构建一个版本的轮廓
代表: 该项目的一个版本 也就是项目的轮廓,或快照
存放:存tree的hash,存file的index
作用区域:
暂存区
缺陷:仅存下了项目轮廓及文件关系,单不知是谁,什么时候,因为什么,种的树(
引出 commit 对象
)补充:
- tree 对象可以指向(含有)另一个tree对象(sub-tree),或者说另一个目录。
指令控制:
查看暂存区状态
$ git ls-files -s
”s” stands for “Stage Index” Area更新暂存区数据
$ git update-index --add --cacheinfo 100644 560a3d89bf36ea10794402f6664740c284d4ae3b ./test.txt
其中:
- 100644 = 普通文件类型
- 100755 = 可执行文件
- 120000 = 符号链接
此外,tree不同于blob在工作区的持续添加,暂存区的内容若已存在则直接覆写,如:
$ git update-index --add --cacheinfo 100644 e1d551f2a5c0d06def7edde8ffe66c6e06f8ca6d ./test.txt
它只会更改上述中同一条text.txt记录的hash值。
将暂存区内容写为一个 Tree 对象
$ git write-tree
(且存入 objects 目录中,并返回 tree 对象的 hash)
查看 Tree 对象内容
$ git cat-file -p 5f5087577ca62d5dbed59ffcaf5f4ad7bd5e1b3e
读取一个 sub-tree 到暂存区
$ git read-tree 5f5087577ca62d5dbed59ffcaf5f4ad7bd5e1b3e
(从hash key读取一个 tree)
commit 对象
代表: 对 tree 进行封装, 加入几条额外描述信息而已
存放:谁,什么时候,因为什么,是第几次,种了哪个树
指令控制:
初次创建提交对象
$ git commit-tree 5f50875 -m "first commit"
或
$ echo "first commit" | git commit-tree 5f50875
(它也会存入 objects 目录中,并返回 commit对象的 hash)
非初次创建提交对象 [ 需指定父级commit对象 (-p) ]
$ git commit-tree 5f50875 -m "new commit" -p 77ca62d5d
查看 commit 对象内容
$ git cat-file -p d592d5dbed59ffcaf5f4ad7bd5effcafe
(一般是一个 tree 的 hash 带上 作者信息)
Git额外笔记
Project snapshot is a Tree
File is a Blob from Tree
Blob is a “key-value” or “hash-object” data
Commit is an encapsulated Tree with author information
Tree can have sub-tree
“ls” stands for “List”
“cd” stands for “Change Directory”
Git换行格式
- LF: Line Feed (Windows 默认换行机制)
- LF样例: \n
- CRLF: Carriage Return Line Feed 包含回车的换行机制 (linux & git 默认换行机制)
- CRLF样例: \r\n
emoji test:
🎨⚡️🔥🐛🚑✨📝🚀🎉💄✅🔒🔖🔧🚨🚧💚⬇️⬆️📌 📌👷📈♻️➕➖🔨🌐✏️💩⏪🔀📦👽🚚📄💥 🍱♿️💡🍻💬🗃🔊🔇👥🚸🏗📱🤡🥚🙈📸⚗🔍🏷️🌱 🚩🥅💫🗑🛂🩹🧐