git仓库组成

git仓库组成

文档: Git - gitrepository-layout Documentation (git-scm.com)

参考: .git文件夹探秘,理解git运作机制-阿里云开发者社区 (aliyun.com)

1.仓库区./git/

执行ls -Fl .git 可以看到.git目录内结构如下

1
2
3
4
5
6
7
8
9
10
11
12
COMMIT_EDITMSG
HEAD
ORIG_HEAD
FETCH_HEAD
config
description
index
hooks/
info/
logs/
objects/
refs/

文件 COMMIT_EDITMSG

​ 此文件是一个临时文件,存储最后一次提交的信息内容,git commit 命令之后打开的编辑器就是在编辑此文件,而你退出编辑器后,git 会把此文件内容写入 commit 记录。

实际应用:

​ git pull 远程仓库后,新增了很多提交,淹没了本地提交记录,直接 cat .git/COMMIT_EDITMSG 就可以弄清楚最后工作的位置了

文件 HEAD

分支HEAD:通常情况下, HEAD 存储一个分支的 ref,运行:cat .git/HEAD 通常会显示如下,这说明你目前正在 master 分支工作。此时你的任何 commit,默认自动附加到 master 分支之上。

1
ref: refs/heads/master

孤立HEAD:但是当使用过git checkout <commit id>后,会提示如下。这代表HEAD 这个文件中存储的信息已不再是一个分支信息,而是指向一个commit对象。

1
You are in 'detached HEAD' state. You can look around, make experimental changes and  commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. ```

文件 ORIG_HEAD

此文件会在你进行危险操作时备份 HEAD,如以下操作时会触发备份:

1
2
3
4
git reset
git merge
git rebase
git pull

如果需要通过该备份还原,则可以执行git reset --hard ORIG_HEAD # 慎用

文件 FETCH_HEAD

此文件用于追踪远程分支的拉取与合并,例如在使用git pull命令时,其实就是先将远程仓库的HEAD同步到该文件中,然后再将其merge至HEAD指针(注,merge前会将HEAD备份至ORI_HEAD)

文件 config

此文件储存项目本地的配置信息,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#[core] 段的内容跟 git config 命令对应
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
# 用户信息通过git config --local user.xxx <value>来配置,如果没有配置,则使用git全局配置的信息
[user]
name = abc
email = abc@abc.com
# remote 记录远程仓库的信息
[remote "origin"]
url = git@gitlab.xxxx.com/xxx.git
fetch = +refs/heads/*:refs/remotes/origin/*
# branch 表示分支同步设置
[branch "master"]
remote = origin
merge = refs/heads/master
[branch "v2.6.0"]
remote = origin
merge = refs/heads/v2.6.0
[branch "v2.8.0"]
remote = origin
merge = refs/heads/v2.8.0

文件 description

说明这个文件主要用于 GitWeb 的描述,如果我们要启动 GitWeb 可用如下命令:

1
2
# 确保lighttpd已安装: brew install lighttpd
git instaweb --start # 默认会启动 lighttpd 服务并打开浏览器 http://127.0.0.1:1234

文件 index

​ 该文件设计负载,简单来讲这个文件也叫做 git 的暂存区(Staging Area),git add 就是把工作区内的某些文件取部分 stat 抓取的内容并写入 .git/index 文件并存为相应的一条 index entry,多条 index entry 形成一个 tree。

  • git commit 是把上一步形成的 tree 结构及相应的 blob 存储到 objects/ 文件夹下并同时生成一条 commit 记录。

  • git reset 是将刚写入 index 文件的 tree 丢弃,并从 HEAD 中恢复一个 tree。

  • git status 是拿 index 文件中存储的 tree 与工作区内的文件在 stat 层面做对比,并输出变更。

参考: git/racy-git.txt at master · git/git (github.com)

目录 hooks

存放 git hooks,用于在 git 命令前后做检查或做些自定义动作

参考:https://git-scm.com/docs/githooks

目录 info

  • 文件 info/exclude 用于排除规则,与 .gitignore 功能类似。
  • 文件 info/refs (可能包含),用于跟踪各分支的信息。一般通过命令 git update-server-info 生成

目录 logs

​ 存放操作信息记录信息,包括了HEAD指针与各分支指针的记录值

目录 objects

​ 该目录下存储了所有的git对象,

​ 该目录下还有pack路径:由于每次 commit 都会生成许多 hash文件,并且由于 blob 文件都是全量存储的,导致 git 效率下降,于是有了 pack-format,优势:对于大仓库存储效率高;利于网络传输,便于备份;增量存储,优化磁盘空间

该目录下还有info路径:储存关于git对象的额外信息

目录 refs

​ heads目录:存放各分支的指针信息

​ tags目录:存放任意git对象名