简体中文 ▾ 主题 ▾ 最新版本 ▾ 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. 您可以通过创建浅克隆(shallow clone)来拥有一个不完整但本地可用的仓库。请参阅 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 目录本身的条目数量控制在可管理的范围内。此处找到的对象通常称为 *未打包(unpacked)*(或 *松散(loose)*)对象。

objects/pack

打包文件(存储许多压缩对象的单个文件,以及允许它们被随机访问的索引文件)位于此目录中。

objects/info

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

objects/info/packs

此文件用于帮助“哑”传输发现此对象存储中可用的打包文件。每当添加或删除打包文件时,如果仓库要通过“哑”传输发布,则应运行 git update-server-info 来使此文件保持最新。*git repack* 默认执行此操作。

objects/info/alternates

此文件记录了此对象存储从其借用对象的备用对象存储的路径,每行一个路径名。请注意,不仅本地 Git 工具会使用它,HTTP 获取器也会尝试在远程使用它;通常,如果您在 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 的树尖提交对象

refs/tags/name

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

refs/remotes/name

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

refs/replace/<obj-sha1>

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

packed-refs

以更有效的方式记录与 refs/heads/、refs/tags/ 和其他引用相同的信息。请参阅 git-pack-refs[1]。如果设置了 $GIT_COMMON_DIR,则会忽略此文件,而将使用 "$GIT_COMMON_DIR/packed-refs"。

HEAD

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

HEAD 也可以直接记录一个特定的提交,而不是作为一个符号引用指向当前分支。这种状态通常称为 *分离 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

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

common

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

index

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

sharedindex.<SHA-1>

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

info

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

info/refs

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

info/grafts

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

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

info/exclude

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

info/attributes

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

info/sparse-checkout

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

remotes

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

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

logs

对 ref 所做的更改记录存储在此目录中。有关更多信息,请参阅 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 实现 **不得** 操作该仓库;这样做不仅可能产生错误的结果,甚至可能丢失数据。

由于此规则,版本升级应尽量减少。相反,我们通常倾向于以下策略:

  • 升级单个数据文件(例如,索引、打包文件等)的格式版本号。这会将不兼容性限制在这些文件中。

  • 引入新的数据,这些数据在被旧客户端使用时能够优雅地降级(例如,旧客户端会忽略打包位图文件,而只是不利用它们提供的优化)。

整个仓库格式版本升级应仅作为无法独立版本化的更改的一部分。例如,如果要更改对象的连通性规则(reachability rules)或 ref 的锁定规则,这将需要升级仓库格式版本。

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

推出版本升级(无论是整个仓库还是单个文件)的首选策略是让 git 能够读取新格式,并通过配置开关或命令行选项(用于实验或不关心向后兼容性)来允许写入新格式。然后在很长一段时间内,以允许读取能力普及,我们可能会默认切换到写入新格式。

当前定义的格式版本是:

版本 0

这是由 git 的初始版本定义的格式,包括但不限于仓库目录的格式、仓库配置文件以及对象和 ref 的存储。指定 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] 套件的一部分