Git 命令分析(一):git add 与 git commit

  • 主要内容
  1. git add 命令使用,及其底层命令分析
  2. git commit 命令使用,及其底层命令分析

工具包:

  1. 状态查看

    git status

  2. 查看 Git 数据库 中的 Git 对象

    find .git/objects/ -type f

  3. 查看 .git 目录结构【主要是 index 暂存区文件有无】

    ll .git

文章的写作思路:

init project --> create file --> add file --> commit file 每一个过程点,都依次执行上面的工具包中的命令,然后根据内容进行分析,并得出结论

  • 文中涉及到的 Git 命令
# Git 项目初始化
git init

# Git 状态查看
git status

# Git 追踪/添加文件
git add

# Git 提交
git commit

注:文中用到的一些底层命令,请参照我的另一篇博文:Git 底层命令浅析(一)

1. 准备工作
  • 命令:git init
# 初始化一个Git项目
$ git init SimpleGit
Initialized empty Git repository in D:/SimpleGit/.git/

# 进入到 SimpleGit 项目中,以下命令皆在该目录中操作
$ cd SimpleGit/

# 查看状态
$ git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)

# 查看 Git 数据库 中的 Git 对象,为空
$ find .git/objects/ -type f

# 查看 .git 目录结构
$ ll .git
total 7
-rw-r--r-- 1 MSI 197121 130  5月 21 15:23 config
-rw-r--r-- 1 MSI 197121  73  5月 21 15:23 description
-rw-r--r-- 1 MSI 197121  23  5月 21 15:23 HEAD
drwxr-xr-x 1 MSI 197121   0  5月 21 15:23 hooks/
drwxr-xr-x 1 MSI 197121   0  5月 21 15:23 info/
drwxr-xr-x 1 MSI 197121   0  5月 21 15:23 objects/
drwxr-xr-x 1 MSI 197121   0  5月 21 15:23 refs/
  • 注意:.git 目录结构中没有 index 文件
2. 操作分析:git add
2.1 例子-1
  • 操作:create file
# 创建新文件
$ echo "git add" > test.txt

# 查看状态
$ git status
On branch master

No commits yet

Untracked files:
  (use "git add ..." to include in what will be committed)
        test.txt

# 查看 Git 数据库 [结果为空]
$ find .git/objects/ -type f

# 查看 .git 目录结构
$ ll .git
total 7
-rw-r--r-- 1 MSI 197121 130  5月 21 15:23 config
-rw-r--r-- 1 MSI 197121  73  5月 21 15:23 description
-rw-r--r-- 1 MSI 197121  23  5月 21 15:23 HEAD
drwxr-xr-x 1 MSI 197121   0  5月 21 15:23 hooks/
drwxr-xr-x 1 MSI 197121   0  5月 21 15:23 info/
drwxr-xr-x 1 MSI 197121   0  5月 21 15:23 objects/
drwxr-xr-x 1 MSI 197121   0  5月 21 15:23 refs/
  • 注意:index文件依旧不存在
2.2 例子-2
  • 命令:git add
  • 在 例子-1 的基础上进行操作
# 添加 test.txt 文件
$ git add test.txt

# 查看状态
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached ..." to unstage)
          new file:   test.txt

# 查看 Git 数据库
$ find .git/objects/ -type f
.git/objects/32/3e4ff440f6ffa8ed8bde18bc9660d75a8bbff4

# 查看 .git 目录结构
$ ll .git
total 8
-rw-r--r-- 1 MSI 197121 130  5月 21 15:23 config
-rw-r--r-- 1 MSI 197121  73  5月 21 15:23 description
-rw-r--r-- 1 MSI 197121  23  5月 21 15:23 HEAD
drwxr-xr-x 1 MSI 197121   0  5月 21 15:23 hooks/
-rw-r--r-- 1 MSI 197121 104  5月 21 15:40 index
drwxr-xr-x 1 MSI 197121   0  5月 21 15:23 info/
drwxr-xr-x 1 MSI 197121   0  5月 21 15:40 objects/
drwxr-xr-x 1 MSI 197121   0  5月 21 15:23 refs/

# 查看 index 内容
$ cat .git/index
DIRC^▒/▒▒-0^▒/▒▒-0▒2>O▒@▒▒▒▒▒▒▒`▒Z▒▒test.txtƐ=▒ L▒L▒5cF\▒▒N▒▒9
  • 注意:index文件存在,且有内容
2.3 分析
  1. Git 数据库中有Git 对象数据,那么说明,git add 命令是包含 git hash-object 这一命令执行操作:
$ git hash-object -w test.txt
323e4ff440f6ffa8ed8bde18bc9660d75a8bbff4
  • SHA-1值与 .git/objects 目录中的一致
  1. .git 目录中的 index 文件被Git 创建,且有内容。即 git add 是包含 git update-index 这一命令执行操作:
$ git update-index --add --cacheinfo 100644 323e4ff440f6ffa8ed8bde18bc9660d75a8bbff4 test.txt
  1. 由于 Git 数据仓库中,只有一个 Git 对象,即内容为“git add” 的 test.txt 对应的blob对象,故没有生成树对象
2.4 结论
  1. git add 命令的作用有:
  1. 将 指定的文件(如本例中的 test.txt)经算法加密计算后,生成SHA-1值;
  2. 并在 .git/objects 中创建对应的 blob 对象(数据对象);
  3. 然后,将指定的文件的blob对象添加到index 暂存区。
  1. 理论图解
    Git 命令分析(一):git add 与 git commit_第1张图片
3. 操作分析:git commit
3.1 例子-3
  • 命令:git commit

  • 在 例子-2 的基础上进行操作

# 查看状态
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached ..." to unstage)
        new file:   test.txt

# 提交
$ git commit -m "First Commit"
[master (root-commit) 2d6735e] First Commit
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt

# 查看状态
$ git status
On branch master
nothing to commit, working tree clean

# 查看 Git 数据库
$ find .git/objects/ -type f
.git/objects/01/7f3e541890b8662e1b66325df95ab3f9e8af8e
.git/objects/2d/6735e715dd5e2357474b16f96666019a917024
.git/objects/32/3e4ff440f6ffa8ed8bde18bc9660d75a8bbff4
# 查看每一个 Git 对象所属类型及其内容
# 对象-1:017f3e
$ git cat-file -p 017f3e
100644 blob 323e4ff440f6ffa8ed8bde18bc9660d75a8bbff4    test.txt
$ git cat-file -t 017f3e
Tree

# 对象-2:2d6735
$ git cat-file -p 2d6735
tree 017f3e541890b8662e1b66325df95ab3f9e8af8e
author test <[email protected]> 1590049841 +0800
committer test <[email protected]> 1590049841 +0800

First Commit

$ git cat-file -t 2d6735
commit

# 对象-3:323e4f
$ git cat-file -p 323e4f
git add

$ git cat-file -t 323e4f
Blob
3.2 分析
  1. Git 数据库中多了 tree 对象,说明 git commit 命令里包含生成树对象的命令:git write-tree

  2. Git 数据库中多了 commit 对象,说明 git commit 命令里包含生成提交对象的命令:git commit-tree

3.3 结论
  • 图解示意
    Git 命令分析(一):git add 与 git commit_第2张图片
4. 总结

Git 命令分析(一):git add 与 git commit_第3张图片
参考文献:

Pro Git 网址:https://git-scm.com/book/zh/v2
如若想深入探究Git,请阅读该书(免费,开源)

本文属于原创,转载请注明出处

你可能感兴趣的:(VCS,#,Git)