简体中文 ▾ 主题 ▾ 最新版本 ▾ gitrepository-layout 上次更新于 2.49.0

名称

gitrepository-layout - Git 仓库布局

概要

$GIT_DIR/*

描述

一个 Git 仓库有两种不同的形式:

  • 工作树根目录下的 .git 目录;

  • 一个 <project>.git 目录,它是一个 裸仓库(即没有自己的工作树),通常用于通过推送和拉取来与他人交换历史记录。

注意:你也可以在你的工作树根目录有一个纯文本文件 .git,其中包含 gitdir: <path> 以指向实际的仓库目录。这种机制称为 gitfile,通常通过 git submodulegit worktree 命令进行管理。它常用于子模块检出的工作树,以便你在包含的超级项目中 git checkout 一个不包含子模块的分支。这种 checkout 必须移除整个子模块工作树,同时不丢失子模块仓库。

这些事物可能存在于 Git 仓库中。

objects

与此仓库关联的对象存储。通常,对象存储是自给自足的(即其中找到的任何对象所引用的所有对象也都在其中),但也有几种情况会违反这一点。

  1. 你可以通过创建浅克隆来获得一个不完整但本地可用的仓库。参见 git-clone[1]

  2. 你可以使用 objects/info/alternates$GIT_ALTERNATE_OBJECT_DIRECTORIES 机制从其他对象存储中“借用”对象。具有这种不完整对象存储的仓库不适合发布供哑传输(dumb transports)使用,但只要 objects/info/alternates 指向它所借用的对象存储,就没问题。

    如果设置了 $GIT_COMMON_DIR,则此目录将被忽略,转而使用 "$GIT_COMMON_DIR/objects"。

objects/[0-9a-f][0-9a-f]

新创建的对象存储在其自己的文件中。对象被分散到 256 个子目录中,使用 sha1 对象名称的前两个字符,以使 objects 目录中的条目数量保持在可管理的范围内。在此处找到的对象通常被称为 未打包的(或 松散的)对象。

objects/pack

包(以压缩形式存储许多对象的文件,以及允许随机访问的索引文件)在此目录中找到。

objects/info

关于对象存储的附加信息记录在此目录中。

objects/info/packs

此文件用于帮助哑传输发现此对象存储中可用的包。每当添加或移除包时,如果仓库发布供哑传输使用,则应运行 git update-server-info 以保持此文件最新。git repack 默认会这样做。

objects/info/alternates

此文件记录了此对象存储借用对象的备用对象存储的路径,每行一个路径名。请注意,不仅原生的 Git 工具在本地使用它,HTTP fetcher 也尝试远程使用它;如果你在 alternates 文件中使用相对路径(相对于对象数据库,而不是仓库!),这通常会奏效,但如果你使用绝对路径,除非文件系统和 Web URL 中的绝对路径相同,否则将不起作用。另请参阅 objects/info/http-alternates

objects/info/http-alternates

此文件记录了此对象存储借用对象的备用对象存储的 URL,当通过 HTTP 拉取仓库时使用。

refs

引用存储在此目录的子目录中。git prune 命令知道要保留此目录及其子目录中找到的引用可到达的对象。如果设置了 $GIT_COMMON_DIR,则此目录(除了 refs/bisect、refs/rewritten 和 refs/worktree)将被忽略,转而使用 "$GIT_COMMON_DIR/refs"。

refs/heads/name

记录分支 name 的树尖(tip-of-the-tree)提交对象。

refs/tags/name

记录任何对象名称(不一定是提交对象,也不是指向提交对象的标签对象)。

refs/remotes/name

记录从远程仓库复制的分支的树尖提交对象。

refs/replace/<obj-sha1>

记录替换 <obj-sha1> 的对象的 SHA-1。这类似于 info/grafts,并由 git-replace[1] 内部使用和维护。此类引用可以在仓库之间交换,而嫁接(grafts)则不能。

packed-refs

以更高效的方式记录与 refs/heads/、refs/tags/ 等目录相同的信息。参见 git-pack-refs[1]。如果设置了 $GIT_COMMON_DIR,则此文件将被忽略,转而使用 "$GIT_COMMON_DIR/packed-refs"。

HEAD

指向 refs/heads/ 命名空间的符号引用(参见词汇表),描述当前活动的分支。如果仓库未与任何工作树关联(即 裸仓库),则其意义不大,但一个有效的 Git 仓库 必须 有 HEAD 文件;一些高层命令(porcelains)可能会使用它来猜测仓库的指定“默认”分支(通常是 master)。如果指定的分支 name 尚未存在,这是合法的。在一些旧版设置中,它是一个指向当前分支的符号链接,而不是符号引用。

HEAD 也可以直接记录特定的提交,而不是作为指向当前分支的符号引用。这种状态通常被称为 分离头指针(detached HEAD)。有关详细信息,请参见 git-checkout[1]

config

仓库特定的配置文件。如果设置了 $GIT_COMMON_DIR,则此文件将被忽略,转而使用 "$GIT_COMMON_DIR/config"。

config.worktree

在多工作目录设置中,主工作目录的特定于工作目录的配置文件(参见 git-worktree[1])。

branches

一种已弃用的方式,用于存储供 git fetchgit pullgit push 指定 URL 的简写。文件可以存储为 branches/<name>,然后可以将 name 传递给这些命令,以代替 repository 参数。有关详细信息,请参见 git-fetch[1] 中的 REMOTES 部分。此机制是旧版机制,在现代仓库中不太可能找到。如果设置了 $GIT_COMMON_DIR,则此目录将被忽略,转而使用 "$GIT_COMMON_DIR/branches"。

Git 将在 Git 3.0 中停止从此目录读取远程。

hooks

钩子是各种 Git 命令使用的自定义脚本。当运行 git init 时,会安装少量示例钩子,但默认情况下它们都被禁用。要启用它们,必须通过重命名从文件名中移除 .sample 后缀。有关每个钩子的更多详细信息,请阅读 githooks[5]。如果设置了 $GIT_COMMON_DIR,则此目录将被忽略,转而使用 "$GIT_COMMON_DIR/hooks"。

common

当使用多个工作树时,$GIT_DIR 中的大多数文件是每个工作树独立的,除了少数已知例外。然而,common 下的所有文件将在所有工作树之间共享。

index

仓库的当前索引文件。通常在裸仓库中找不到它。

sharedindex.<SHA-1>

共享索引部分,由 $GIT_DIR/index 和其他临时索引文件引用。仅在分离索引模式下有效。

info

有关仓库的附加信息记录在此目录中。如果设置了 $GIT_COMMON_DIR,则此目录将被忽略,转而使用 "$GIT_COMMON_DIR/info"。

info/refs

此文件帮助哑传输发现此仓库中可用的引用。如果仓库发布供哑传输使用,则每次创建或修改标签或分支时,都应通过 git update-server-info 重新生成此文件。这通常通过 hooks/update 钩子完成,该钩子由 git-receive-pack 命令在你 git push 到仓库时运行。

info/grafts

此文件记录了伪造的提交祖先信息,以假装一个提交的父提交集合与实际创建该提交时不同。每行一个记录描述一个提交及其伪父提交,通过列出它们 40 字节的十六进制对象名称(用空格分隔并以换行符结尾)。

请注意,嫁接机制已过时,可能导致仓库间对象传输出现问题;请参阅git-replace[1]以获取更灵活和健壮的实现相同功能的系统。

info/exclude

按照高层命令(Porcelains)的惯例,此文件存储排除模式列表。.gitignore 是按目录的忽略文件。git statusgit addgit rmgit clean 会查看它,但核心 Git 命令不会查看它。另请参阅:gitignore[5]

info/attributes

定义要分配给路径的属性,类似于按目录的 .gitattributes 文件。另请参阅:gitattributes[5]

info/sparse-checkout

此文件存储稀疏检出模式。另请参阅:git-read-tree[1]

remotes

存储 URL 和默认引用名称的简写,供通过 git fetchgit pullgit push 命令与远程仓库交互时使用。有关详细信息,请参见 git-fetch[1] 中的 REMOTES 部分。此机制是旧版机制,在现代仓库中不太可能找到。如果设置了 $GIT_COMMON_DIR,则此目录将被忽略,转而使用 "$GIT_COMMON_DIR/remotes"。

Git 将在 Git 3.0 中停止从此目录读取远程。

logs

对此引用的更改记录存储在此目录中。有关更多信息,请参见 git-update-ref[1]。如果设置了 $GIT_COMMON_DIR,则此目录(除了 logs/HEAD)将被忽略,转而使用 "$GIT_COMMON_DIR/logs"。

logs/refs/heads/name

记录对名为 name 的分支尖端所做的所有更改。

logs/refs/tags/name

记录对名为 name 的标签所做的所有更改。

shallow

这类似于 info/grafts,但由浅克隆机制内部使用和维护。参见 git-clone[1]git-fetch[1]--depth 选项。如果设置了 $GIT_COMMON_DIR,则此文件将被忽略,转而使用 "$GIT_COMMON_DIR/shallow"。

commondir

如果此文件存在,并且 $GIT_COMMON_DIR(参见 git[1])未显式设置,则将其设置为此文件中指定的路径。如果指定的路径是相对路径,则它相对于 $GIT_DIR。带有 commondir 的仓库在没有 "commondir" 所指向的仓库时是不完整的。

modules

包含子模块的 Git 仓库。

worktrees

包含链接工作树的管理数据。每个子目录包含链接工作树中与工作树相关的部分。如果设置了 $GIT_COMMON_DIR,则此目录将被忽略,此时将使用 "$GIT_COMMON_DIR/worktrees"。

worktrees/<id>/gitdir

一个文本文件,包含指向此处的 .git 文件的绝对路径。这用于检查链接的仓库是否已被手动移除,以及是否不再需要保留此目录。此文件的修改时间(mtime)应在每次访问链接仓库时更新。

worktrees/<id>/locked

如果此文件存在,则链接的工作树可能位于便携设备上且不可用。此文件的存在阻止 worktrees/<id> 被自动或通过 git worktree prune 手动修剪。该文件可能包含解释仓库为何被锁定的字符串。

worktrees/<id>/config.worktree

工作目录特定的配置文件。

Git 仓库格式版本

每个 Git 仓库都在其 config 文件的 core.repositoryformatversion 键中标记有一个数字版本。此版本指定了在磁盘仓库数据上操作的规则。不理解磁盘仓库所宣传的特定版本的 Git 实现 不得 在该仓库上操作;这样做不仅有产生错误结果的风险,而且实际上有数据丢失的风险。

由于此规则,版本升级应保持在绝对最小值。相反,我们通常倾向于以下策略:

  • 提升单个数据文件(例如,索引、包文件等)的格式版本号。这将不兼容性仅限于这些文件。

  • 引入新数据,这些数据在旧客户端使用时可以优雅降级(例如,旧客户端会忽略包位图文件,它们只是无法利用其提供的优化)。

整个仓库格式的版本升级只应是无法独立版本化更改的一部分。例如,如果有人要更改对象的触达规则或锁定引用的规则,这将需要提升仓库格式版本。

请注意,这仅适用于直接访问仓库的磁盘内容。一个只理解格式 0 的旧客户端仍然可以通过 git:// 连接到使用格式 1 的仓库,只要服务器进程理解格式 1 即可。

推出版本升级(无论是整个仓库还是单个文件)的首选策略是:教 Git 读取新格式,并允许通过配置开关或命令行选项写入新格式(用于实验或不关心与旧 Git 版本向后兼容的人)。然后,在允许读取功能普及的长时间之后,我们可以默认切换到写入新格式。

当前定义的格式版本为:

版本 0

这是 Git 初始版本定义的格式,包括但不限于仓库目录、仓库配置文件以及对象和引用存储的格式。指定 Git 的完整行为超出了本文档的范围。

版本 1

此格式与版本 0 相同,但有以下例外:

  1. 读取 core.repositoryformatversion 变量时,支持版本 1 的 Git 实现 必须 同时读取在配置文件 extensions 部分中找到的任何配置键。

  2. 如果版本 1 仓库指定了运行中的 Git 尚未实现的任何 extensions.* 键,则操作 不得 继续。同样,如果实现不理解任何已知键的值,则操作 不得 继续。

请注意,如果在配置文件中未指定任何扩展,则 core.repositoryformatversion 应该 设置为 0(将其设置为 1 没有任何好处,并且会使仓库与旧版 Git 实现不兼容)。

已定义的扩展在 git-config[1]extensions.* 部分中给出。任何希望定义新扩展的实现都应在此处进行说明,以声明其名称。

GIT

Git[1] 套件的一部分

scroll-to-top