# Git commit (提交) 对象

**URL:** <https://www.isharkfly.com/t/git-commit/10952>\
**Category:** 软件技术\
**Created:** [April 4, 2015, 4:55am UTC](https://www.isharkfly.com/t/git-commit/10952 "2015-04-04T04:55:39Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![honeymoose](https://www.isharkfly.com/user_avatar/www.isharkfly.com/honeymoose/32/20796_2.png) [@honeymoose](https://www.isharkfly.com/u/honeymoose)\
**Post date:** [April 4, 2015, 4:55am UTC](https://www.isharkfly.com/t/git-commit/10952/1 "2015-04-04T04:55:39Z")

</div>

你现在有三个 tree 对象，它们指向了你要跟踪的项目的不同快照，可是先前的问题依然存在：必须记往三个 SHA-1 值以获得这些快照。你也没有关于谁、何时以及为何保存了这些快照的信息。commit 对象为你保存了这些基本信息。

要创建一个 commit 对象，使用 commit-tree 命令，指定一个 tree 的 SHA-1，如果有任何前继提交对象，也可以指定。从你写的第一个 tree 开始：

`$ echo 'first commit' | git commit-tree d8329f
fdf4fc3344e67ab068f836878b6c4951e3b15f3d`

通过 cat-file 查看这个新 commit 对象：

[code]$ git cat-file -p fdf4fc3  
tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579  
author Scott Chacon [schacon@gmail.com](mailto:schacon@gmail.com) 1243040974 -0700  
committer Scott Chacon [schacon@gmail.com](mailto:schacon@gmail.com) 1243040974 -0700

first commit[/code]

commit 对象有格式很简单：指明了该时间点项目快照的顶层树对象、作者/提交者信息（从 Git 设置的user.name 和 user.email中获得)以及当前时间戳、一个空行，以及提交注释信息。  
接着再写入另外两个 commit 对象，每一个都指定其之前的那个 commit 对象：

`$ echo 'second commit' | git commit-tree 0155eb -p fdf4fc3
cac0cab538b970a37ea1e769cbbde608743bc96d
$ echo 'third commit' | git commit-tree 3c4e9c -p cac0cab
1a410efbd13591db07496601ebc7a059dd55cfe9`

每一个 commit 对象都指向了你创建的树对象快照。出乎意料的是，现在已经有了真实的 Git 历史了，所以如果运行 git log 命令并指定最后那个 commit 对象的 SHA-1 便可以查看历史：

[code]$ git log --stat 1a410e  
commit 1a410efbd13591db07496601ebc7a059dd55cfe9  
Author: Scott Chacon [schacon@gmail.com](mailto:schacon@gmail.com)  
Date: Fri May 22 18:15:24 2009 -0700

```
third commit

```

bak/test.txt | 1 +  
1 files changed, 1 insertions(+), 0 deletions(-)

commit cac0cab538b970a37ea1e769cbbde608743bc96d  
Author: Scott Chacon [schacon@gmail.com](mailto:schacon@gmail.com)  
Date: Fri May 22 18:14:29 2009 -0700

```
second commit

```

new.txt | 1 +  
test.txt | 2 ±  
2 files changed, 2 insertions(+), 1 deletions(-)

commit fdf4fc3344e67ab068f836878b6c4951e3b15f3d  
Author: Scott Chacon [schacon@gmail.com](mailto:schacon@gmail.com)  
Date: Fri May 22 18:09:34 2009 -0700

```
first commit

```

test.txt | 1 +  
1 files changed, 1 insertions(+), 0 deletions(-)[/code]

真棒。你刚刚通过使用低级操作而不是那些普通命令创建了一个 Git 历史。这基本上就是运行 git add和 git commit 命令时 Git 进行的工作 ──保存修改了的文件的 blob，更新索引，创建 tree 对象，最后创建 commit 对象，这些 commit 对象指向了顶层 tree 对象以及先前的 commit 对象。这三类 Git 对象 ── blob，tree 以及 commit ── 都各自以文件的方式保存在 .git/objects 目录下。以下所列是目前为止样例中的所有对象，每个对象后面的注释里标明了它们保存的内容：

`$ find .git/objects -type f
.git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341 # tree 2
.git/objects/1a/410efbd13591db07496601ebc7a059dd55cfe9 # commit 3
.git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a # test.txt v2
.git/objects/3c/4e9cd789d88d8d89c1073707c3585e41b0e614 # tree 3
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30 # test.txt v1
.git/objects/ca/c0cab538b970a37ea1e769cbbde608743bc96d # commit 2
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 # 'test content'
.git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579 # tree 1
.git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 # new.txt
.git/objects/fd/f4fc3344e67ab068f836878b6c4951e3b15f3d # commit 1`

如果你按照以上描述进行了操作，可以得到如图 9-3 所示的对象图。

![](https://www.isharkfly.com/images/transparent.png)

图 9-3. Git 目录下的所有对象

REF：[http://cwiki.ossez.com/pages/viewpage.action?pageId=7045952](http://cwiki.ossez.com/pages/viewpage.action?pageId=7045952)
