Git 的核心部分是一个简单的键值对数据库(key-value data store)。 你可以向 Git 仓库中插入任意类型的内容,它会返回一个唯一的键,通过该键可以在任意时刻再次取回该内容。

存数据

用 git hash-object 创建一个新的数据对象并将它手动存入 Git 数据库中:
该命令可将任意数据保存于 .git/objects 目录(即 对象数据库),并返回指向该数据对象的唯一的键。

  1. $ echo 'test content' | git hash-object -w --stdin
  2. d670460b4b4aece5915caf5c68d12f560a9fe3e4

在这种最简单的形式中,git hash-object 会接受你传给它的东西,而它只会返回可以存储在 Git 仓库中的唯一键。 -w 选项会指示该命令不要只返回键,还要将该对象写入数据库中。 最后,—stdin 选项则指示该命令从标准输入读取内容;若不指定此选项,则须在命令尾部给出待存储文件的路径。

如果再次查看 objects 目录,那么可以在其中找到一个与新内容对应的文件。 这就是开始时 Git 存储内容的方式——一个文件对应一条内容, 以该内容加上特定头部信息一起的 SHA-1 校验和为文件命名。 校验和的前两个字符用于命名子目录,余下的 38 个字符则用作文件名。

  1. $ find .git/objects/ -type f
  2. .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4

取数据

用 cat-file 命令从 Git 那里取回数据,为 cat-file 指定 -p 选项可指示该命令自动判断内容的类型,并为我们显示大致的内容:

  1. $ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
  2. test content

存文件内容

  1. $ echo "test1" > test.txt
  2. $ cat test.txt
  3. test1
  4. $ git hash-object -w test.txt
  5. warning: in the working copy of 'test.txt', LF will be replaced by CRLF the next time Git touches it
  6. a5bce3fd2565d8f458555a0c6f42d0504a848bd5
  7. $ echo "test2" > test.txt
  8. $ git hash-object -w test.txt
  9. warning: in the working copy of 'test.txt', LF will be replaced by CRLF the next time Git touches it
  10. 180cf8328022becee9aaa2577a8f84ea2b9f3827
  11. $ find .git/objects/ -type f
  12. .git/objects/18/0cf8328022becee9aaa2577a8f84ea2b9f3827
  13. .git/objects/a5/bce3fd2565d8f458555a0c6f42d0504a848bd5
  14. .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4

缺陷

  • 记住文件的每一个版本所对应的 SHA-1 值并不现实
  • 另一个问题是,在这个(简单的版本控制)系统中,文件名并没有被保存——我们仅保存了文件的内容。 上述类型的对象我们称之为 数据对象(blob object)

查看对象的类型

利用 git cat-file -t 命令,可以让 Git 告诉我们其内部存储的任何对象类型,只要给定该对象的 SHA-1 值:

  1. $ git cat-file -t 180cf8328022becee9aaa2577a8f84ea2b9f3827
  2. blob
  3. $ git cat-file -t d670460b4b4aece5915caf5c68d12f560a9fe3e4
  4. blob