Git之.git目录
.git
目录是 Git 用来存储项目版本控制信息的核心目录,下面是.git
目录中重要文件和文件夹的作用:
HEAD
HEAD
文件指向当前处于的分支。其内容通常为:
1 | ref: refs/heads/main |
这表明当前分支为main
。
如果内容为ref: refs/heads/feat
,表明当前分支为feat
Git 的设计是基于引用(refs)体系的,所有引用都存储在 .git/refs 目录下,其中refs/heads/ 用于存储分支
config
存储对应项目的 Git 配置信息,例如远程仓库地址、体验化选项等。文件内容大致为:
1 | [core] |
description
GitWeb 服务中用于显示项目描述,通常在本地使用时没有实际作用。
objects/
Git 中最重要的文件夹,存储所有对象(如 commit 、tree 、blob,以及annotated tag)。不同对象根据对象的标识码和数据内容保存。
Git 中的所有对象(commit、tree、blob 和 annotated tag)在存储时都会经过以下两步处理:
- 添加头部信息:包括对象类型和内容长度;
- 使用 zlib 压缩:将对象压缩为二进制格式存储。
想要查看对象存储的信息可以使用命令git cat-file -p <hash-id>
Commit 对象
记录一次提交操作,包含提交描述信息和对应根目录的 tree 对象。文件内容:
1 | tree <tree-hash> |
tree-hash
:指向根目录的 tree 对象。parent-hash
:指向上一个提交的哈希值(如果有多个父提交,则记录多个)。author
:提交作者的信息,包括名字、邮箱和时间戳。committer
:实际提交人信息(可能与作者不同)。<commit-message>
:提交的描述信息。
Tree 对象
存储目录中文件和子目录的结构信息,相当于一个目录的实时展示。文件内容:
1
<file-mode> <type> <hash> <filename>
file-mode
:文件的权限信息(如普通文件、可执行文件、子目录等)。type
:对象类型(blob 或 tree)。hash
:对应 blob 或子 tree 对象的标识码。filename
:文件或目录的名称。
示例:1
2100644 blob 789abcd file.txt
040000 tree 123efgh subdir
Blob 对象
存储文件的内容,没有文件名称或目录结构信息,是 Git 存储原始文件数据的核心实体。
文件内容:直接存储文件内容(存储时经过添加头部和zlib压缩,故不是明文),不包含元数据。
- 例如,一个文本文件
hello.txt
,内容为Hello, world!
,其 blob 对象使用git cat-file -p
查看后显示:1
Hello, world!
Annotated Tag 对象
标记一个实体对象,通常用于永久标记,包含创建者、时间和描述信息。文件内容:
1
2
3
4
5
6object <object-hash>
type <type>
tag <tag-name>
tagger <tagger-name> <email> <timestamp>
<tag-message>
object-hash
:指向被标记对象(如 commit)的哈希值。type
:对象的类型(如 commit、tree、blob)。tag-name
:标签的名称。tagger
:标签创建者的信息。<tag-message>
:标签的描述信息。
示例:
1 | object f3a23bc4f1e8e5a1d07e8f5f0f7c12ef8f7d1234 |
这些对象是 Git 存储和追踪文件历史的核心,采用哈希值(SHA-1 或其他算法)唯一标识,确保了数据完整性和高效性。
refs/
存放分支和标签信息,这些参照指向对应的 commit。包括三个个重要存储目录:
refs/heads/
:存放分支信息;refs/heads/xxx
:xxx
为本地分支名,其文件中存储该分支最新提交的hash id
refs/remote/origin/
:存放远程分支信息refs/heads/xxx
:xxx
为远程分支名,其文件中存储该分支最新提交的hash id
refs/tags/
:存放标签信息。refs/tags/xxx
:xxx
为附注标签名,其文件中存储该Annotated Tag的hash id
hooks/
存放各种钩子脚本,用于在 Git 操作时执行自定义操作。其中.sample后缀的文件只是样例,需要将后缀去除并赋予执行权限后才能作为真正的脚本。脚本编写可以使用任何支持的脚本语言,如 Bash、Python 等
1 | ls hooks |
例子:检查提交信息格式(commit-msg),确保提交信息以特定前缀开头
1 |
|
Hooks 不会随仓库一起推送到远程服务器。推荐将 Hooks 脚本存储在项目目录(如 .githooks/)中,并通过文档指导团队成员启用。
info/
包含额外的配置信息,例如exclude
文件,设置本地排除要求。
logs/
记录分支和HEAD
的历史变化记录,便于优化和借助调试。
index
Git 的 暂存区(staging area)的核心数据结构,用于管理文件的快照。它记录了工作区中文件的状态信息,是 Git 的暂存操作、差异计算以及提交生成的关键组件,是一个二进制文件。
packed-refs
将亚气式存储的参照(如分支)压缩为单个文件,减少文件总数,提高性能。
COMMIT_EDITMSG
存储最近一次 commit 的消息,便于检查和修改。
ORIG_HEAD
记录最近一次重覆或结合之前的 HEAD 位置,通常用于撤销操作。
理解.git
目录中各文件和文件夹的作用,能让我们更深入了解 Git 运作机制,并能在工作中更好地排查问题和优化流程。对于初学者,探索.git
目录中的内容是学习 Git 的重要一步;对于高级用户,理解该目录能让你更好地自定义 Git 操作和优化项目管理。