(一)仓库创建与配置 - .git 目录的结构与作用
文章目录
- 1. .git 目录的结构
- 2. 核心部分详细讲解
- 2.1 objects/ - Git 对象数据库(核心中的核心)
- 2.2 refs/ - 引用目录
- 2.3 HEAD 文件
- 2.4 index 文件(二进制)
- 2.5 config 文件
- 2.6 hooks/ 目录
- 2.7 info/ 目录
- 3. 总结
1. .git 目录的结构
.git/
├── HEAD # 指向当前所在的分支或提交
├── config # 本项目特有的 Git 配置
├── description # 仅供 GitWeb 程序使用
├── index # 暂存区(Stage)的信息
├── hooks/ # 客户端或服务端的钩子脚本
│ ├── pre-commit.sample # 提交前触发的脚本示例
│ ├── post-update.sample # 推送后触发的脚本示例
│ └── ...
├── info/ # 存放全局性排除文件(不纳入版本控制)的模式
│ └── exclude
├── objects/ # Git 对象数据库(核心!)
│ ├── pack/ # 打包后的对象(用于优化)
│ │ ├── pack-xxx.pack # 打包的数据文件
│ │ └── pack-xxx.idx # 打包数据的索引文件
│ └── ...
│ ├── 12/ # 对象的前两位作为目录名
│ │ └── 3456789... # 对象的剩余部分作为文件名
│ ├── ab/
│ └── ...
└── refs/ # 存放分支和标签的指针├── heads/ # 本地分支指针│ ├── main # `main` 分支的最新提交哈希│ └── develop # `develop` 分支的最新提交哈希├── tags/ # 标签指针│ └── v1.0.0 # `v1.0.0` 标签指向的提交哈希└── remotes/ # 远程跟踪分支指针└── origin/ # 远程仓库 `origin` 的相关指针├── HEAD # 远程仓库 `origin` 的默认分支└── main # 远程分支 `origin/main` 的最新提交哈希
2. 核心部分详细讲解
2.1 objects/ - Git 对象数据库(核心中的核心)
这是 Git 的数据存储中心,所有文件、目录、提交等数据都以 对象(Object) 的形式存储在这里。Git 使用 SHA-1 哈希算法为每个对象生成一个唯一的 40 位十六进制码(如 d670460b4b4aece5915caf5c68d12f560a9fe3e4),并以前两位作为目录名,后 38 位作为文件名存储。
对象主要有四种类型:
- Blob 对象:
- 作用:存储文件内容。它只关心内容,不关心文件名和权限。项目中每一个文件的每一个版本,其内容都会对应一个唯一的
Blob对象。 - 创建:当你执行
git add时,工作区文件的内容就会被压缩并生成Blob对象存入objects/。
- 作用:存储文件内容。它只关心内容,不关心文件名和权限。项目中每一个文件的每一个版本,其内容都会对应一个唯一的
- Tree 对象:
- 作用:相当于一个目录快照。它记录了某个提交时刻,工作目录的结构。它包含一系列条目,每个条目指向一个
Blob对象(文件)或另一个Tree对象(子目录),并记录了对应的文件名、权限和类型。 - 创建:当你执行
git commit时,会根据当前暂存区的状态创建一个Tree对象。
- 作用:相当于一个目录快照。它记录了某个提交时刻,工作目录的结构。它包含一系列条目,每个条目指向一个
- Commit 对象:
- 作用:存储一次提交信息。它指向一个顶层
Tree对象(代表项目根目录的快照),包含作者、提交者、提交时间、提交说明等信息,以及一个或多个父提交的SHA-1哈希(用于形成提交历史)。 - 创建:
git commit命令会创建一个Commit对象。 - 示例:一个
Commit对象的内容大致如下:
- 作用:存储一次提交信息。它指向一个顶层
tree 92b8b6ff5f41000a7d7c5e83c679d0d6d6e79c6e
parent 7b34a8e88566d7a72d4a1fb2c67e4b94c7e77a9b
author Your Name <email@example.com> 1691234567 +0800
committer Your Name <email@example.com> 1691234567 +0800Your commit message here.
- Tag 对象:
- 作用:存储一个标签信息(附注标签)。它指向一个特定的
Commit对象,包含标签名、标签者、日期和信息。轻量标签则只是一个指向提交的引用,不创建对象。
- 作用:存储一个标签信息(附注标签)。它指向一个特定的
objects/pack/目录:- 作用:为了节省空间和效率,
Git会定期将许多松散的对象打包成一个包文件(.pack)和一个索引文件(.idx)。索引文件帮助快速定位包文件内的对象。这个过程通过git gc(垃圾回收)自动触发。
- 作用:为了节省空间和效率,
2.2 refs/ - 引用目录
引用(Reference)是指向 Commit 对象的指针,它们是人类可读的名称,代替了难记的 SHA-1 哈希。
refs/heads/:- 作用:存储所有本地分支。每个文件就是一个分支,文件名是分支名,文件内容是该分支最新提交
(HEAD)的SHA-1哈希。当你在这个分支上做新提交时,对应文件的内容会自动更新。
- 作用:存储所有本地分支。每个文件就是一个分支,文件名是分支名,文件内容是该分支最新提交
refs/tags/:- 作用:存储所有标签。每个文件就是一个标签,指向一个特定的提交(轻量标签)或一个
Tag对象(附注标签)
- 作用:存储所有标签。每个文件就是一个标签,指向一个特定的提交(轻量标签)或一个
refs/remotes/:- 作用:存储远程跟踪分支。例如,
refs/remotes/origin/main文件记录了远程仓库origin上main分支最后一次已知的提交哈希。你执行git fetch时,更新的是这里的指针,而不是refs/heads/下的本地分支。
- 作用:存储远程跟踪分支。例如,
2.3 HEAD 文件
- 作用:这是一个符号引用,它指向当前检出的分支。它通常存储一个路径,如
ref: refs/heads/main,意思是“HEAD 目前指向 main 分支”。 - 分离头指针状态:如果你直接检出了一个提交(如
git checkout <commit-hash>),HEAD文件的内容会直接变成一个SHA-1哈希,而不是引用路径,这就是“分离头指针”状态。
2.4 index 文件(二进制)
- 作用:这就是传说中的暂存区
(Staging Area)。它是一个二进制文件,充当工作区和版本库之间的缓存。它保存了下次提交将要包含的文件信息(包括文件名、SHA-1、时间戳、权限等),其结构本质上是一个指向objects/中对象的Tree。 - 操作:
git add将文件信息写入index;git commit根据index的内容创建Tree和Commit对象。
2.5 config 文件
- 作用:存储当前
Git仓库的局部配置。你通过git config --local设置的选项(如用户信息、远程仓库地址、分支行为等)都保存在这里。它的优先级高于全局配置(~/.gitconfig)
2.6 hooks/ 目录
- 作用:存放钩子脚本。这些是特定事件(如提交、推送、接收等)发生时,
Git会自动执行的脚本。你可以利用它们来自动化工作流,例如在提交前运行代码检查、在推送后部署代码等。默认情况下,里面的文件都是带.sample扩展名的示例,移除扩展名即可启用它们。
2.7 info/ 目录
info/exclude 文件:- 作用:用于设置仅对本仓库生效的忽略规则。它与
.gitignore文件功能类似,但区别在于.gitignore会纳入版本控制,可以共享给所有协作者;而info/exclude不会,只对你的本地仓库有效。适合忽略一些你个人开发环境特有的文件。
- 作用:用于设置仅对本仓库生效的忽略规则。它与
3. 总结
objects/是 Git 的数据库,存储所有数据。refs/是 Git 的指针和标签,让我们可以用友好的名字(如分支名)来访问数据。HEAD是当前工作位置的指针,告诉我们现在在哪。index是构建下次提交的蓝图(暂存区)。config和hooks/用于定制化 Git 的行为。
