
## Git 目录结构

一个 Git 仓库的 `.git` 目录大致如下：

```
.git/
├── *config          # 本地配置（大小写敏感、远程URL、用户名邮箱等）
├── description      # 仅供 GitWeb 使用，无需关心
├── *HEAD            # 当前被检出的分支
├── index            # 暂存区信息
│
├── hooks/           # 钩子脚本（执行 Git 命令时自动触发特定操作）
├── info/
│   └── exclude      # 全局排除文件（不想记入 .gitignore 的忽略模式）
├── logs/            # 记录所有操作（reflog）
├── *objects/        # 存储所有数据内容
│   ├── {SHA-1}/     # Git 对象目录（commit / tree / blob）
│   ├── info/
│   └── pack/        # 打包压缩的对象文件
└── *refs/           # 指向提交对象的指针
    ├── heads/       # 本地分支
    ├── remotes/     # 远程分支
    └── tags/        # 标签
````

（一开始缺少 index 和 logs，objects 里缺少 SHA-1,refs 缺少 tags）
## Git 对象

Objects 目录下存储三种核心对象：

| 对象类型             | 说明                         | 示例           |
| ---------------- | -------------------------- | ------------ |
| **blob**（数据对象）   | 存储文件内容（不包含文件名）             | 文件快照         |
| **tree**（树对象）    | 存储文件名和目录结构，指向 blob 或子树     | 类似文件系统目录项    |
| **commit**（提交对象） | 存储提交信息（作者、时间、父提交、指向的 tree） | 一次 commit 记录 |

Git 通过 SHA-1 哈希值来标识每个对象，例如 `24b9da6552252987aa493b52f8696cd6d3b00373`。

## 打包与压缩

Git 最初向磁盘存储对象时采用“松散”对象格式；但为了节省空间，Git 会定期将多个对象打包成一个“包文件”（packfile）。触发打包的时机：

- 松散对象过多时自动执行 `git gc`
- 手动执行 `git gc`
- 向远程服务器推送时也会触发打包

## 引用（References）

Git 将一些常用的 SHA-1 值存储在文件中，用文件名替代，这些别名称为**引用**（refs）。三种引用类型：

- `refs/heads/` — 本地分支
- `refs/remotes/` — 远程分支
- `refs/tags/` — 标签

```bash
git reflog                          # 查看 HEAD 和分支的引用日志
git ls-remote origin                # 查看远程所有引用
````

> Git 的“快照”核心思想在 [Git 核心概念与基础操作](app://obsidian.md/Git%20%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5%E4%B8%8E%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C) 中有详细说明。