git commit 对象数据结构的文件格式是什么?

2024-01-06

上下文:我希望能够搜索我的 git 提交消息和提交,而不必执行令人费解的复杂 git grep 命令,所以我决定看看 git 提交消息是如何存储的。

我查看了 .git 文件夹,在我看来,提交存储在

.git/objects 

.git 对象文件夹包含一堆名称类似于 a6 和 9b 的文件夹。这些文件夹每个都包含一个名称类似于提交 sha 2f29598814b07fea915514cfc4d05129967bf7 的文件。当我在文本编辑器中打开其中一个文件时,我得到了乱码。

  1. 这个乱码是什么文件格式/ git commit 对象是如何存储的?
  2. 在这个 git commit 日志中,文件夹 9b 包含一个提交 sha

    aed8a9f773efb2f498f19c31f8603b6cb2a4bc
    

    为什么,是否存在多个提交 sha 会存储在文件 9b 中的情况?

  3. 有没有办法将这些乱码转换为纯文本,以便我可以在文本编辑器中搞乱提交?


创建一个最小的示例并对格式进行逆向工程

在创建任何包文件之前创建一个简单的存储库(git gc, git config gc.auto, git-prune-packed...),使用以下方法之一解压提交对象:如何使用命令行工具DEFLATE来提取git对象? https://stackoverflow.com/questions/3178566/deflate-command-line-tool

export GIT_AUTHOR_DATE="1970-01-01T00:00:00+0000"
export GIT_AUTHOR_EMAIL="[email protected] /cdn-cgi/l/email-protection"
export GIT_AUTHOR_NAME="Author Name" \
export GIT_COMMITTER_DATE="2000-01-01T00:00:00+0000" \
export GIT_COMMITTER_EMAIL="[email protected] /cdn-cgi/l/email-protection" \
export GIT_COMMITTER_NAME="Committer Name" \

git init

# First commit.
echo
touch a
git add a
git commit -m 'First message'
# (for python2, remove the two `.buffer`s in the next line)
python -c "import zlib,sys;sys.stdout.buffer.write(zlib.decompress(sys.stdin.buffer.read()))" \
  <.git/objects/45/3a2378ba0eb310df8741aa26d1c861ac4c512f | hd

# Second commit.
echo
touch b
git add b
git commit -m 'Second message'
# (for python2, remove the two `.buffer`s in the next line)
python -c "import zlib,sys;sys.stdout.buffer.write(zlib.decompress(sys.stdin.buffer.read()))" \
  <.git/objects/74/8e6f7e22cac87acec8c26ee690b4ff0388cbf5 | hd

输出是:

Initialized empty Git repository in /home/ciro/test/git/.git/

[master (root-commit) 453a237] First message
 Author: Author Name <[email protected] /cdn-cgi/l/email-protection>
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a
00000000  63 6f 6d 6d 69 74 20 31  37 34 00 74 72 65 65 20  |commit 174.tree |
00000010  34 39 36 64 36 34 32 38  62 39 63 66 39 32 39 38  |496d6428b9cf9298|
00000020  31 64 63 39 34 39 35 32  31 31 65 36 65 31 31 32  |1dc9495211e6e112|
00000030  30 66 62 36 66 32 62 61  0a 61 75 74 68 6f 72 20  |0fb6f2ba.author |
00000040  41 75 74 68 6f 72 20 4e  61 6d 65 20 3c 61 75 74  |Author Name <aut|
00000050  68 6f 72 40 65 78 61 6d  70 6c 65 2e 63 6f 6d 3e  |[email protected] /cdn-cgi/l/email-protection>|
00000060  20 30 20 2b 30 30 30 30  0a 63 6f 6d 6d 69 74 74  | 0 +0000.committ|
00000070  65 72 20 43 6f 6d 6d 69  74 74 65 72 20 4e 61 6d  |er Committer Nam|
00000080  65 20 3c 63 6f 6d 6d 69  74 74 65 72 40 65 78 61  |e <committer@exa|
00000090  6d 70 6c 65 2e 63 6f 6d  3e 20 39 34 36 36 38 34  |mple.com> 946684|
000000a0  38 30 30 20 2b 30 30 30  30 0a 0a 46 69 72 73 74  |800 +0000..First|
000000b0  20 6d 65 73 73 61 67 65  0a                       | message.|
000000ba

[master 748e6f7] Second message
 Author: Author Name <[email protected] /cdn-cgi/l/email-protection>
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 b
00000000  63 6f 6d 6d 69 74 20 32  32 33 00 74 72 65 65 20  |commit 223.tree |
00000010  32 39 36 65 35 36 30 32  33 63 64 63 30 33 34 64  |296e56023cdc034d|
00000020  32 37 33 35 66 65 65 38  63 30 64 38 35 61 36 35  |2735fee8c0d85a65|
00000030  39 64 31 62 30 37 66 34  0a 70 61 72 65 6e 74 20  |9d1b07f4.parent |
00000040  34 35 33 61 32 33 37 38  62 61 30 65 62 33 31 30  |453a2378ba0eb310|
00000050  64 66 38 37 34 31 61 61  32 36 64 31 63 38 36 31  |df8741aa26d1c861|
00000060  61 63 34 63 35 31 32 66  0a 61 75 74 68 6f 72 20  |ac4c512f.author |
00000070  41 75 74 68 6f 72 20 4e  61 6d 65 20 3c 61 75 74  |Author Name <aut|
00000080  68 6f 72 40 65 78 61 6d  70 6c 65 2e 63 6f 6d 3e  |[email protected] /cdn-cgi/l/email-protection>|
00000090  20 30 20 2b 30 30 30 30  0a 63 6f 6d 6d 69 74 74  | 0 +0000.committ|
000000a0  65 72 20 43 6f 6d 6d 69  74 74 65 72 20 4e 61 6d  |er Committer Nam|
000000b0  65 20 3c 63 6f 6d 6d 69  74 74 65 72 40 65 78 61  |e <committer@exa|
000000c0  6d 70 6c 65 2e 63 6f 6d  3e 20 39 34 36 36 38 34  |mple.com> 946684|
000000d0  38 30 30 20 2b 30 30 30  30 0a 0a 53 65 63 6f 6e  |800 +0000..Secon|
000000e0  64 20 6d 65 73 73 61 67  65 0a                    |d message.|
000000eb

那么我们推导出格式如下:

  • 顶层:

    commit {size}\0{content}
    

    where {size}是字节数{content}.

    所有对象类型都遵循相同的模式。

  • {content}:

    tree {tree_sha}
    {parents}
    author {author_name} <{author_email}> {author_date_seconds} {author_date_timezone}
    committer {committer_name} <{committer_email}> {committer_date_seconds} {committer_date_timezone}
    
    {commit message}
    

    where:

    • {tree_sha}:此提交指向的树对象的 SHA。

      这代表顶级 Git 存储库目录。

      该 SHA 来自树对象的格式:Git 树对象的内部格式是什么? https://stackoverflow.com/questions/14790681/what-is-the-internal-format-of-a-git-tree-object

    • {parents}:父提交对象的可选列表,形式为:

      parent {parent1_sha}
      parent {parent2_sha}
      ...
      

      如果没有父母,则列表可以为空,例如用于存储库中的第一次提交。

      两个父级发生在定期合并提交中。

      可以有两个以上的父母git merge -Xoctopus,但这不是常见的工作流程。这是一个例子:https://github.com/cirosantilli/test-octopus-100k https://github.com/cirosantilli/test-octopus-100k

    • {author_name}: e.g.: Ciro Santilli。不能包含<, \n

    • {author_email}: e.g.: [email protected] /cdn-cgi/l/email-protection。不能包含>, \n

    • {author_date_seconds}:自 1970 年以来的秒数,例如946684800是 2000 年的第一秒

    • {author_date_timezone}: e.g.: +0000 is UTC

    • 提交者字段:类似于作者字段

    • {commit message}: 随意的。

我制作了一个最小的 Python 脚本,它生成一个 git 存储库,并在以下位置进行了一些提交:https://github.com/cirosantilli/test-git-web-interface/blob/864d809c36b8f3b232d5b0668917060e8bcba3e8/other-test-repos/util.py#L83 https://github.com/cirosantilli/test-git-web-interface/blob/864d809c36b8f3b232d5b0668917060e8bcba3e8/other-test-repos/util.py#L83

我用它来做一些有趣的事情,比如:

  • GitHub 上连续使用时间最长的用户是谁? https://stackoverflow.com/questions/20099235/who-is-the-user-with-the-longest-streak-on-github/27742165#27742165
  • https://www.quora.com/Which-GitHub-repo-has-the-most-commits/answer/Ciro-Santilli https://www.quora.com/Which-GitHub-repo-has-the-most-commits/answer/Ciro-Santilli
  • https://github.com/isaacs/github/issues/1344 https://github.com/isaacs/github/issues/1344

下面是标签对象格式的类似分析:git tag 对象的格式是什么以及如何计算其 SHA? https://stackoverflow.com/questions/10986615/what-is-the-format-of-a-git-tag-object-and-how-to-calculate-its-sha/52193441#52193441

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

git commit 对象数据结构的文件格式是什么? 的相关文章

随机推荐

  • 如何增加 JVM 内存? [复制]

    这个问题在这里已经有答案了 你好 我想知道我是否可以根据我的应用程序增加 JVM 内存 如果可以 我该如何增加 JVM 内存 我怎样才能知道 JVM 的大小 启动 JVM 时 可以调整两个参数以满足您的内存需求 Xms
  • 如何通过 Jayway JsonPath 展平带有嵌套列表的 json?

    目前我需要根据配置处理一些 json 结果 而不是硬代码 例如 json如下 data orderNo CG8310150 details skuId 4384 amount 2 skuId 4632 amount 5 orderNo CG
  • 如何让greatmonkey 检查页面上是否找到文本

    我确实在谷歌和用户脚本网站上做了一些研究 但没有成功找到答案 那么基本上我如何检查页面上是否找到特定文本 并且文本没有特殊标签或任何东西 对于 FF GM 来说 一个粗略但快速的方法 if Text you are looking for
  • Android随机多项选择测验:如何识别正确答案

    我正在尝试为 Android 创建一个随机多项选择测验 我想显示字符串数组中的随机问题 另一个字符串数组的相应答案显示在四个选项之一中 其他三个选项将来自另一个字符串数组 该数组将用于随机提供所有问题的 错误 答案 两个问题 有没有更好的方
  • Mono 不写入设置默认值

    这是我的问题 如果我只使用一个 Windows 窗体项目并且仅调用 Settings Default Save 运行时 Mono 会创建一个 user config 文件 其中包含每个设置的默认值 很好 到目前为止一切都很好 但现在我添加了
  • CSS 不显示任何内容且不透明动画且关键帧不起作用

    我有一个非常基本的 HTML 片段 其目的是从display none to display block不透明度从 0 变为 1 我使用的是 Chrome 浏览器 它使用 webkit前缀作为偏好并做了 webkit keyframes设置
  • Excel-DNA:F# 初始化错误 [错误] 方法未注册

    作为一名新手 F 开发人员 我尝试创建一个简单的 Excel DNA 函数 如下所示
  • 启用 DMA 的 UART Tx 模式

    我已经为 UART 在传输模式下编写了一个简单的设备驱动程序 并启用了 DMA 和中断 我使用的硬件是 omap 4460 pandaboard 其中加载了 Linux 3 4 下面我分享一下相关部分的代码 在开放阶段 dma map io
  • 使用 Angularjs 在选择下拉列表中设置默认值

    我有一个对象如下 我必须将其显示为下拉菜单 var list id 4 name abc id 600 name def id 200 name xyz 在我的控制器中 我有一个带有值的变量 该值决定在下拉列表中默认选择数组中的上述三项中的
  • 当我尝试运行在 GitHub 上找到的代码时,我遇到了这个问题。 Pydot 和 graphivz 已安装但仍然出现此错误[重复]

    这个问题在这里已经有答案了 2022 07 19 18 41 58 081967 W tensorflow stream executor platform default dso loader cc 64 Could not load d
  • 如何告诉 ProGuard 保留私有字段而不指定每个字段

    这是我的课 package com tools app holiday public class Holiday private String name private Calendar dateFrom Calendar getInsta
  • Git 从以前的提交范围创建分支?

    我有一个操作系统项目的一堆提交 我想将最后的 20 个提交提取到另一个分支 这样我就可以拉取请求 我怎么能这样做呢 原因是我可能有 150 次提交 但其中大部分都是为了更大的贡献 但尚未准备好 但下一个版本即将发布 Thanks 你可以这样
  • 如何在 mysql 中将 csv 文件导出到我的计算机

    我正在尝试将表以 csv 格式从远程服务器导出到我的台式计算机 我有这个代码 select from order into outfile C Users Sleep Shop Desktop MySQL Scripts outfile c
  • Scala 和 Java 的构建器库

    我需要一个可以从 Scala 和 Java 调用的构建器库 在 Scala 中使用默认的命名参数就足够简单了 但是我如何从 Java 调用这段代码呢 见下文 或者也许我应该使用两种语言都更通用的流畅 API Scala case class
  • Python:如何将输出捕获到文本文件? (现在仅捕获 530 行中的 25 行)

    我已经潜伏在 SO 上做了相当多的工作 并进行了大量的搜索和阅读 但我也必须承认 总的来说 我在编程方面是一个相对菜鸟 我正在努力边学边学 所以我一直在使用 Python 的 NLTK 在下面的脚本中 我可以让一切正常工作 除了它只写多屏幕
  • 为什么只允许动态方法跳过可见性检查?

    我正在移植使用的代码DynamicMethod广泛允许预编译 以获得更好的冷启动性能 我注意到DynamicMethod可以进行即时编译并在跳过可见性检查的情况下执行 这允许它们访问私有嵌套类型 但普通程序集不能 或者不能 我没有看到任何明
  • MVC3 远程属性 - 验证

    我有一个班级管理员 public class Admin public virtual int AdminId get set Remote UsernameAvailable Admins Display Name lblUsername
  • 当其他未缓冲的查询处于活动状态时,PDO 无法执行查询

    我知道这必须是一个简单的修复 并且我部分理解为什么会出现此错误 但不知道如何修复它 我查看了文档 但除了使用缓冲查询选项之外找不到其他解决方案 我也尝试过 但它不起作用 错误是 当其他未缓冲的查询处于活动状态时 PDO 无法执行查询 该错误
  • 跨域资源共享(CORS)概念

    我对跨域 JavaScript 的概念有疑问 有一个服务器 例如 amazon com 只有选定的域才能使用其网络服务 所以肯定的是 如果我尝试从本地使用他们的服务 我就不能 我在控制台上看到了这个 跨源请求被阻止 同源策略不允许读取 远程
  • git commit 对象数据结构的文件格式是什么?

    上下文 我希望能够搜索我的 git 提交消息和提交 而不必执行令人费解的复杂 git grep 命令 所以我决定看看 git 提交消息是如何存储的 我查看了 git 文件夹 在我看来 提交存储在 git objects git 对象文件夹包