目录
[1. 创建文件](#1. 创建文件)
[2. 将 file1 添加到暂存区](#2. 将 file1 添加到暂存区)
[3. 查看 Git 状态](#3. 查看 Git 状态)
[4. 提交 file1](#4. 提交 file1)
[5. 再次查看状态](#5. 再次查看状态)
[6. 查看提交日志](#6. 查看提交日志)
[7. 提交 file2 和 file3](#7. 提交 file2 和 file3)
[8. 一行显示 Git 日志](#8. 一行显示 Git 日志)
[9. 观察 .git 目录变化](#9. 观察 .git 目录变化)
[10. 查看 Git 对象](#10. 查看 Git 对象)
[11. 验证 commit 只提交暂存区内容](#11. 验证 commit 只提交暂存区内容)
[12. Git 管理的是内容变化](#12. Git 管理的是内容变化)
[13. 修改 ReadME 并查看 diff](#13. 修改 ReadME 并查看 diff)
[14. 提交 ReadME 修改](#14. 提交 ReadME 修改)

本文记录 Git 中 add、commit、status、log、diff 以及 .git 对象库的基本观察。
核心结论:git add 把工作区改动放入暂存区,git commit 把暂存区内容提交到本地仓库。
1. 创建文件
使用 touch 创建三个文件
touch file1 file2 file3

此时目录中一共有三个文件:
- file1
- file2
- file3
2. 将 file1 添加到暂存区
git add file1

git add file1 这条命令把 file1 放入暂存区中。
3. 查看 Git 状态
git status
file1 已经进入暂存区,等待 commit 提交。并且发现了 ReadME 文件被修改但是没有提交修改后的文件,还发现了 file2 和 file3 两个文件没有追踪。

4. 提交 file1
git commit -m "file1"
使用 git commit -m "file1" 把暂存区中的 file1 提交到本地仓库。

5. 再次查看状态
git status
使用 git status 查看当前 git 状态,发现暂存区中的 file1 已经不在,只剩下 ReadME 的修改文件未提交,file2 和 file3 未追踪。

6. 查看提交日志
git log
使用 git log 查看所有的 git 日志
发现已经有了 add file1 的日志
这里的 132ca0eafba09c8e5202b734693a65f1a91e3620 是经过 hash 计算过后的版本号,后面我们可以使用这里的版本号来进行回退到该版本。
还有Author:这一行里面就是我们配置的 用户名 和 邮箱 起作用了,就能看到是谁来进行的提交。

说明:
-
132ca0eafba09c8e5202b734693a65f1a91e3620是经过哈希计算得到的版本号,也可以理解为提交对象的 ID。 -
后续可以使用这个版本号回退到该版本。
-
Author一行显示的是配置的用户名和邮箱,用于标识是谁进行了提交。
7. 提交 file2 和 file3
git add file2 file3
使用 git add file2 file3 提交两个文件
发现 file2 和 file3 都进入了暂存区中

使用 git commit -m "add file2 file3" 把 file2 和 file3 提交到工作区
git commit -m "add file2 file3"

再次查看日志:使用 git log 查看本次记录在git 日志中被记录

8. 一行显示 Git 日志
git log --pretty=oneline
git log --pretty=oneline 可以把 Git 日志以一行一条的形式打印出来。
其中 HEAD -> master 指向的就是我们最近的一次提交。
9. 观察 .git 目录变化
经过add 和 commit 之后 .git 文件发生了哪些变化
使用 tree .git 查看结构

使用 cat .git/HEAD 查看HEAD 里指向的是我们的master分支

使用 cat .git/refs/heads/master 查看 master 分支引用和我们的当前 git log 查看到的版本号一致

4b1a3958c0889c77218bbe85240b26bf51b95a0d 这里面的 4b 就是 tree .git 里面的objects 的4b文件夹,1a3958c0889c77218bbe85240b26bf51b95a0d 就是文件名
10. 查看 Git 对象
使用 git cat-file -p 4b1a3958c0889c77218bbe85240b26bf51b95a0d 查看最新版本的对象,发现上一次提交的 commit id 和 提交的人是谁,描述就是我们使用 git commit -m "XXX" 中输入的描述。
git cat-file -p 4b1a3958c0889c77218bbe85240b26bf51b95a0d

可以看到:
-
上一次提交的 commit ID
-
提交者信息
-
提交描述,也就是
git commit -m "XXX"中输入的描述
继续查看其中的 tree 对象:
git cat-file -p e64dd387eab7b264b10b76d9bbcbd26cabd7938f
tree 对象记录的是目录结构和文件快照信息。也就是说,每次 commit 操作都会生成或引用 Git 对象,并存放到 .git/objects 中。
可以使用下面的方式查看某个提交:
git cat-file -p <commit-id>
需要理解的是,Git 对象库中主要包含:
-
blob:文件内容 -
tree:目录结构 -
commit:提交信息
所以 Git 存储的不是简单的一整个文件副本,而是基于内容的对象和快照。
11. 验证 commit 只提交暂存区内容
查看当前文件使用 la 命令 发现只有file1 file2 file3 ReadME .git
使用 touch file4 创建出 file4

使用 git add file4 将 file4 放入暂存区

现在使用 touch file5 创建 file5 文件

使用 git commit -m "add file" 提交到本地仓库,发现只有 file4 被提交了,file5 没有被提交。

使用 git status 查看发现 file5 并没有进入暂存区中,所以没有被提交

git 追踪管理是修改,而不是文件
它的objects 对象库里面存储的是我们修改的内容,而不是一阵个文件
12. Git 管理的是内容变化
Git 追踪管理的是修改和内容快照,而不是简单地"按文件"管理。
对象库中存储的是 Git 对象,例如文件内容对象、目录树对象和提交对象。每次提交会根据暂存区生成快照,未变化的内容通常会复用已有对象。
13. 修改 ReadME 并查看 diff
使用 vim ReadME 修改 ReadME 文件

把 hello hello 修改为 hello 你好!

使用 esc ,输入 :wq 保存退出,这时候工作区中的 ReadME 文件已经被修改
使用 git status 命令查看 git 状态,发现git已经发现 ReadME 文件被修改,而且暂存区中无内容

使用 git diff ReadME 命令查看 ReadME 文件,这里 a 是改动前(版本库中存在的),b 是改动后(工作区中的)
14. 提交 ReadME 修改
使用 git add ReadME 和 git status 提交并查看git 状态,发现他说我们需要将改变提交到本地仓库

使用git commit -m "modify ReadME" 提交 ReadMe 文件

使用 git status 查看你发现暂存区是干净的,没有需要commit的文件
