最后,修订和引用都是指向Git对象的指针,那么两者都有什么意义呢?
tf7tbtn21#
......就是这样(?)。就这样...差不多了Git使用文件系统作为数据库。引用存储在两个地方之一。.git/refs和.git/packed-refs。.git/refs/为每个引用都包含一个文件。例如,主分支在.git/refs/heads/main中。标签v1.2.3在.git/refs/tags/v1.2.3中。该文件包含它引用的提交的SHA。当您请求main时,git会搜索这些目录,当找到匹配的文件名时,它会从文件中读取SHA。这就是为什么您也可以将主分支称为main、heads/main和refs/heads/main;它们只是要搜索的相对文件路径。如果目录树中有很多引用,并且不能扩展,那么搜索目录树会变得很麻烦,尤其是在网络驱动器上。所以git偶尔会将这些引用“打包”到一个文件.git/packed-refs中。这是一个简单的文件,每个引用对应一行,格式为<sha> <ref>。Git打开文件,读取直到找到匹配的引用,然后使用sha。这样一个小而经常被引用的文件很可能会保留在操作系统的缓存中,使得后续的读取非常快。Git会定期写一个新的packfile。使用文件系统作为数据库而不是像SQLite或二进制文件格式这样的数据库,是一种非常快速、非常优雅且非常可移植的解决方案。您可以在Pro Git的Git Internals章节中阅读更多关于packfiles和references的信息。
.git/refs
.git/packed-refs
.git/refs/
.git/refs/heads/main
.git/refs/tags/v1.2.3
main
heads/main
refs/heads/main
<sha> <ref>
ibrsph3r2#
Git引用(即Git对象的别名)可以是Git版本号(即Git对象查询)example-1,但反之则不然example-2,因为:
ref
rev
[示例-1]:git log main[示例-2]:git log main..topic(即使修订版main..topic使用两个引用,main和topic)。
git log main
git log main..topic
main..topic
topic
多对一关系:
┌─────────┐ ┌──────┐ │ Git │ * 1 │ Git │ │reference├────────────►│object│ └─────────┘ └──────┘
Git引用指向单个Git对象****2,多个Git引用可以指向同一个Git对象。
详细说明这一点:
[1]:或“别名”、“指针”、“标签”等[2]Git对象有4种类型:tree, blob, commit和tag。[3]:For now,至少。例如:
[~/my-project]$ git cat-file --batch-check --batch-all-objects 10d5ab2b502faadff680c6904cbd60d7a8b5d0af tree 34 11f61d01b7af5c657c13109777a577ef6a3d3a7a tree 34 1d41fcffd528c1ee950b630d939407fe5f3b22d0 tree 34 40267b7fcf0d4490a45e0d70618a5d7b63895a60 blob 25 5a6bdceda9ae20b80fed214776b4423f522f2d01 tree 68 5b76730490981c045b186fd9651f91f0492c5b07 blob 12 5f45e9c854941c72deb9d36fb3e95e4feb4d698f commit 234 64a77169fe44d06b082cbe52478b3539cb333d45 tree 34 6692c9c6e231b1dfd5594dd59b32001b70060f19 commit 237 740481b1d3ce7de99ed26f7db6687f83ee221d67 blob 50 83cb3ab54ca122d439bdd9997a21f399cac69692 blob 16 864333c0eccabdaba6df27166ac616c922569b47 blob 42 abb08192ed875ef73fa66029994aa2f6700befd0 commit 231 c277976fce0b2b32b954a66d4345730b5b08f1db commit 230 e67cb07f9ddb0ecd0f88fcf36093d8d8bf928b75 commit 175 e95dd8284a84af5418c0dcf9cbdc0b1061624907 blob 25 [~/my-project]$ git show-ref --head --dereference 5f45e9c854941c72deb9d36fb3e95e4feb4d698f HEAD c277976fce0b2b32b954a66d4345730b5b08f1db refs/heads/main 5f45e9c854941c72deb9d36fb3e95e4feb4d698f refs/heads/topic c277976fce0b2b32b954a66d4345730b5b08f1db refs/remotes/origin/main 5f45e9c854941c72deb9d36fb3e95e4feb4d698f refs/remotes/origin/topic e95dd8284a84af5418c0dcf9cbdc0b1061624907 refs/tags/balabab e95dd8284a84af5418c0dcf9cbdc0b1061624907 refs/tags/lofa 5f45e9c854941c72deb9d36fb3e95e4feb4d698f refs/tags/miez
一对多关系
┌────────┐ ┌──────┐ │ Git │ 1 * │ Git │ │revision├──────────────┤object│ └────────┘ └──────┘
Git revision是一个解析为一个或多个Git对象的Git对象查询。
Git版本号是一个符合a special notation syntax(或“版本号查询系统”)的字符串,用于明确选择一个或多个Git对象2。这类似于数据库系统(例如PostgreSQL)如何使用查询语言(例如SQL),但在这种情况下,Git是数据库系统,而版本语法是查询语言。这种类比似乎也适用于版本能够引用一系列Git对象。例如,给定此提交历史,
* ebc9079 (HEAD -> main) karikittyom * 982b806 edes * ccccccc tyukom * bbbbbbb megis van * aaaaaaa egy felpenzem
修订版aaaaaaa..ccccccc将返回提交bbbbbbb和ccccccc:
aaaaaaa..ccccccc
bbbbbbb
ccccccc
$ git log aaaaaaa..ccccccc commit cccccccccccccccccccccccccccccccccccccccc Author: toraritte Date: Mon Jan 9 03:29:24 2023 +0000 tyukom commit bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb Author: toraritte Date: Mon Jan 9 03:29:24 2023 +0000 megis van
相对5****修订查询的基本构建块是
<sha1>
dae86e1950b1277e545cee180551750029cfe735
dae86e
其中references用作开始遍历图形的起点。[5]:这里使用“relative”很重要,因为还有:/<text>和:\[<n>:\]<path>不需要锚。至少,gitrevisions文档中的每个符号都可以归结为上面的结论:
:/<text>
:\[<n>:\]<path>
gitrevisions
<describeOutput>
v1.7.4.2-679-g3bee7fb
git describe
[<branchname>]@{upstream}
master@{upstream}
@{u}
<rev>^{<type>}
v0.99.8^{commit}
<rev>
2条答案
按热度按时间tf7tbtn21#
......就是这样(?)。
就这样...差不多了
Git使用文件系统作为数据库。引用存储在两个地方之一。
.git/refs
和.git/packed-refs
。.git/refs/
为每个引用都包含一个文件。例如,主分支在.git/refs/heads/main
中。标签v1.2.3在.git/refs/tags/v1.2.3
中。该文件包含它引用的提交的SHA。当您请求main
时,git会搜索这些目录,当找到匹配的文件名时,它会从文件中读取SHA。这就是为什么您也可以将主分支称为main
、heads/main
和refs/heads/main
;它们只是要搜索的相对文件路径。如果目录树中有很多引用,并且不能扩展,那么搜索目录树会变得很麻烦,尤其是在网络驱动器上。所以git偶尔会将这些引用“打包”到一个文件
.git/packed-refs
中。这是一个简单的文件,每个引用对应一行,格式为<sha> <ref>
。Git打开文件,读取直到找到匹配的引用,然后使用sha。这样一个小而经常被引用的文件很可能会保留在操作系统的缓存中,使得后续的读取非常快。Git会定期写一个新的packfile。
使用文件系统作为数据库而不是像SQLite或二进制文件格式这样的数据库,是一种非常快速、非常优雅且非常可移植的解决方案。
您可以在Pro Git的Git Internals章节中阅读更多关于packfiles和references的信息。
ibrsph3r2#
TL;DR
Git引用(即Git对象的别名)可以是Git版本号(即Git对象查询)example-1,但反之则不然example-2,因为:
ref
只能代表一个单个Git对象,但每个Git对象可以有多个ref
。rev
可以解析为一个或多个Git对象。[示例-1]:
git log main
[示例-2]:
git log main..topic
(即使修订版main..topic
使用两个引用,main
和topic
)。Git引用(
ref
s)多对一关系:
Git引用指向单个Git对象****2,多个Git引用可以指向同一个Git对象。
详细说明这一点:
[1]:或“别名”、“指针”、“标签”等
[2]Git对象有4种类型:tree, blob, commit和tag。
[3]:For now,至少。
例如:
Git版本号(
rev
s)一对多关系
Git revision是一个解析为一个或多个Git对象的Git对象查询。
Git版本号是一个符合a special notation syntax(或“版本号查询系统”)的字符串,用于明确选择一个或多个Git对象2。
这类似于数据库系统(例如PostgreSQL)如何使用查询语言(例如SQL),但在这种情况下,Git是数据库系统,而版本语法是查询语言。这种类比似乎也适用于版本能够引用一系列Git对象。
例如,给定此提交历史,
修订版
aaaaaaa..ccccccc
将返回提交bbbbbbb
和ccccccc
:ref
s和rev
s的连接revision表示法是一个查询系统,通过遍历有向无环图或DAG来到达repo 中的任何Git对象(或它们的范围)。
相对5****修订查询的基本构建块是
<sha1>
,例如dae86e1950b1277e545cee180551750029cfe735
,dae86e
)<sha1>
)其中references用作开始遍历图形的起点。
[5]:这里使用“relative”很重要,因为还有
:/<text>
和:\[<n>:\]<path>
不需要锚。至少,
gitrevisions
文档中的每个符号都可以归结为上面的结论:<describeOutput>
,例如v1.7.4.2-679-g3bee7fb
git describe
“finds the most recent tag that is reachable from a commit". tag是Git引用,git describe
已经有了自己的revision-esque表示法。[<branchname>]@{upstream}
,e.g.master@{upstream}
,@{u}
分支名称是Git引用,其余是修订查询符号。<rev>^{<type>}
,例如v0.99.8^{commit}
其中<rev>
意味着“* 在递归时取消引用对象 *”,所以最后我们将得到一个标记或<sha1>
。