如何计算提交、树和 blob 的哈希值?

2024-02-05

我对如何计算提交、树和 blob 的 SHA-1 哈希值感到困惑。按照本文 https://gist.github.com/masak/2415865,提交哈希值是根据以下因素计算的:

  1. 提交的源树(分解为所有子树和 blob)
  2. 父提交 sha1
  3. 作者信息
  4. 提交者信息(对,这些是不同的!)
  5. 提交消息

树和 blob 哈希也涉及相同的因素吗?


Git 有时被称为“内容可寻址文件系统”。哈希值是地址,它们基于各种对象的内容。因此,为了知道哈希值是基于什么,我们只需要知道各个对象的内容即可。

Blobs

A blob只是一个八位位组流。而已。它类似于以下概念文件内容在 Unix 文件系统中。

因此,blob 的哈希值仅基于其内容,blob 没有元数据。

Trees

A tree将名称和权限与其他对象(blob 或树)相关联。一棵树只是一个四元组的列表(permission, type, hash, name)。例如,一棵树可能如下所示:

100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README
100644 blob 8f94139338f9404f26296befa88755fc2598c289 Rakefile
040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 lib

请注意第三个条目,它本身就是一棵树。

一棵树类似于一个目录特殊文件在 Unix 文件系统中。

同样,哈希值基于树的内容,这意味着基于其叶子的名称、权限、类型和哈希值。

Commits

A commit及时记录树的快照以及一些元数据以及快照是如何形成的。一次提交包括:

  • (任意数量)父提交(包括零)的哈希值列表
  • 树的哈希值
  • 提交消息
  • 提交元数据(提交日期和提交者姓名)
  • 创作元数据(创作日期和作者姓名)

提交的哈希值基于这些。

Tags

Tags不是上述意义上的对象。它们不是对象存储的一部分,也没有哈希值。他们是参考到物体。 (注意:任何对象都可以被标记,而不仅仅是提交,尽管这是正常的用例。)

带注释的标签

An 带注释的标签不同的是:它is对象存储的一部分。

带注释的标签存储:

  • 提交的哈希值
  • 标签消息
  • 标记元数据(标记器名称和标记日期)

与所有其他对象一样,哈希值是根据所有对象计算的,仅此而已。

签名标签

A 签名标签就像带注释的标签,但添加了加密签名。

Notes

Notes允许您将任意提交与任意 Git 对象关联。

笔记的存储稍微复杂一些。实际上,注释只是一次提交(包含一棵树,其中包含包含注释内容的 blob)。 Git 为注释创建一个特殊分支,注释提交与其“注释对象”之间的关联发生在那里。我不熟悉具体如何。

但是,由于注释只是一次提交,并且关联发生在外部,因此注释的哈希值与任何其他提交相同。


存储格式

存储格式包含一个简单的标头。实际存储(和散列)的内容是标头,后跟 NULL 八位字节,后跟对象内容。

标头包含对象内容的类型和长度,以 ASCII 编码。因此,包含字符串的 blobHello, World以 ASCII 编码如下:

blob 12\0Hello, World

And that是散列和存储的内容。

其他类型的对象具有更结构化的格式,因此树对象将以标头开始tree <length of content in octets>\0接下来是严格定义的、结构化的、序列化的树表示。

提交也是如此。

大多数格式都是基于简单 ASCII 的文本格式。例如,大小不是编码为二进制整数,而是编码为十进制整数,每个数字表示为相应的 ASCII 字符。

压缩

计算出哈希值后,使用zlib-deflate对包含头的对象对应的八位字节流进行压缩,并将得到的八位字节流根据哈希值存储在文件中;默认在目录中

.git/objects/<first two characters of the hash>/<remaining hash>

Packs

上述存储格式称为松散对象格式,因为每个对象都是单独存储的。有一种更高效的存储格式(也用作网络传输格式),称为packfile.

Packfile 是重要的速度和存储优化,但它们相当复杂,因此我不打算详细描述它们。

作为第一个近似,包文件由连接成单个文件和第二个文件的所有未压缩对象组成,第二个文件包含对象在包文件中所在位置的索引。然后将包文件作为一个整体进行压缩,这可以实现更好的压缩比,因为该算法还可以找到冗余between对象而不仅仅是within单个对象。 (例如,如果您有两个几乎相同的 blob 修订版……这在 SCM 中是一种常态。)

它不使用 zlib-deflate,而是使用二进制增量压缩算法。它还使用某些启发式方法来确定如何将对象放置在 packfile 中,以便将可能具有较大相似性的对象紧密地放置在一起。 (Delta算法实际上无法看到whole一次打包文件,这会消耗太多内存,而是在打包文件上的滑动窗口上运行;启发式尝试确保相似的对象落在同一窗口内。)其中一些启发式是:查看树与斑点关联的名称,并尝试将具有相同名称的名称放在一起,尝试将具有相同名称的名称放在一起。相同的文件扩展名靠近,尝试保持后续修订靠近等等。

四处探索

松散(即未打包)对象只是 zlib 压缩的。取消它们的放气,只需查看它们即可了解它们的结构。请注意,未压缩的八位字节流是exactly正在哈希什么;对象以压缩方式存储,但在压缩之前进行哈希处理。

这是一个简单的 Perl 单行代码来解压 https://stackoverflow.com/a/3185337/2988(这是膨胀吗?)流:

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

如何计算提交、树和 blob 的哈希值? 的相关文章

  • 如何完全删除使用init创建的git存储库?

    我创建了一个 git 存储库git init 我想完全删除它并启动一个新的 Git 将其所有文件保存在 git目录 只要删除那个并再次初始化即可 如果你找不到它 那是因为它被隐藏了 In Windows 7 you need to go t
  • svn diff 或 git diff 中带有 at 符号的“@@...@@”元行是什么意思?

    当我使用svn diff or git diff它显示如下行 1 5 1 9 他们的意思是什么 这些称为 c hunk 标头并包含范围信息 它们周围有双标志 它们的格式如下 l s l s where l是起始行号并且s是 c hunk 应
  • git push 无法在 cron 作业中工作

    我目前正在清理 CentOS 6 服务器上其他人留下的烂摊子 有一个应用程序需要每6小时备份一次到github帐户 有一个脚本负责准备数据并负责 git add 和 git commit git Push 由 expect 脚本负责 这样做
  • gitk 无法在 macOS 10.14 (Mojave) 上启动

    当我尝试在 macOS Mojave 10 14 4 上运行 gitk 时 出现以下错误 Error in startup script file System Library ScriptingDefinitions CocoaStand
  • git LFS 如何比 git 更高效地跟踪和存储二进制数据?

    我知道 git LFS 导致 git 在文本文件中存储字符串 指针 然后 git LFS 下载该目标二进制文件 这样 远程 git 服务器上的 git repos 就会更小 但是 git LFS 仍然必须存储二进制文件 所以在我看来 本地存
  • Git:需要递归地'git rm'所有bin和obj文件夹的内容

    有人不小心将所有 bin 和 obj 文件夹提交到我们的存储库 大约有 40 个这样的文件夹 我想做一个git rm r在所有这些文件夹上 有命令可以执行此操作吗 有备份 find type d name bin exec git rm r
  • GitHub 恢复或重置? [复制]

    这个问题在这里已经有答案了 正如您在图片中看到的 我正在功能 forum kolo 3 中工作 我决定完成该功能并将其合并到开发中 但没有将更改推送到远程开发 因此它只是本地更改 然后我意识到这是一个坏主意 现在我想删除这个合并 就像它从未
  • “git push heroku master”仍然要求身份验证

    我已经执行了 heroku login 但是当我尝试推送时 仍然要求我进行身份验证 git push heroku master Username for https git heroku com
  • 保序最小完美哈希函数

    我想用 C 为字典中的单词实现 OPMPH 函数 我该怎么做 Thanks 你看过这些论文吗 http dx doi org 10 1016 0020 0190 92 90220 P http dx doi org 10 1016 0020
  • 如何从现有 git 存储库中的文件夹创建新的 git 存储库?

    我想在现有 git 存储库下的文件夹中创建一个新的 git 存储库 我希望将历史记录保留在新存储库中 如何创建这个新的 git 存储库 您可以克隆它 然后在克隆上应用过滤器分支 以便拆分该存储库 仅提取所需的目录 及其完整历史记录 See
  • 行结尾:Git merge 创建重复项而不会发生冲突

    Git 自动合并问题 当在两个不同的分支文件中提交相同的代码时 其中一个分支代码在开始时具有额外的 CRLF LF 合并时 它会自动合并文件 并会创建重复项 而不会产生任何冲突 请尽早指教 下图显示了文本文件中所有可能的符号 注意 分支 A
  • 如何临时更改git ssh用户进行远程推送?

    是否可以临时更改 ssh 用户为 git Push Remote Master 而不会弄乱 git config 或 git Remote 或使用整个远程 URL root host gitrepo git push otheruser r
  • Git:如何处理不同的shebang

    人们如何处理本地和远程之间的不同 shebang 例如 我的本地 python 是 usr bin python 而我的 Web 主机是位于 local bin python 的专用 python 首席开发人员的 ruby 可能位于 usr
  • 来自远程标签的 Git 分支

    我创建了一个从另一个远程存储库镜像的新本地 git 存储库 git init git remote add original url git pull original master git remote add origin url gi
  • 如何在 Git 中创建多个阶段

    使用 Git 时 可以按照以下方式暂存文件https githowto com staging changes https githowto com staging changes 所以通常 git add file1 git commit
  • 使用git在测试和生产环境之间同步数据库

    我正在尝试在 php mysql 应用程序的开发过程中实现 git 到目前为止 我已经设置了 git repos 并且我们正在使用本地计算机进行测试 并且我们成功地将其用于文件 但我真的不知道如何处理数据库 服务器上有一个 cron 脚本
  • 使用 `git for-each-ref` 和 `git log` 显示 origin 上每个远程分支上的最新提交

    完成后git fetch all prune为了从远程存储库获取引用 我现在想查看每个分支上的最新提交origin 命令 git for each ref format refname short grep origin 列出所有 16 个
  • 执行“挤压和合并”后可能出现问题?

    I used Squash and Merge用于合并dev分支到main因为我不想要来自的一些提交消息dev出现在的分支main但现在我发现main比 dev 提前 1 次提交 并且该图显示 两者之间没有联系dev and main 这是
  • git:更改样式(空白)而不更改所有权/责任?

    我们有一个庞大的 古老的代码库 需要大量的清理 我们一直都有编码标准 每个人都试图遵循它们 但它们没有得到执行 因此随着时间的推移 出现了很多违规行为 其中许多只是空格问题 例如使用制表符而不是空格 或者使用制表符代替空格 不应有任何空格
  • xcode 中的 Git(无分支)

    在我的 ios 项目中 我使用 git 作为 scm Xcode 存储库列表包括 至少在 Xcode 中 无分支 的内容 前段时间我可能检查了以前的提交 但没有创建分支 从那时起我已经做出了大约 40 次提交 现在我想从我的下一个最后提交分

随机推荐

  • svn https: “ra_serf: SSL 通信期间发生错误”

    我知道这与其他帖子的标题相同 但我搜索了又搜索 但找不到解决方案 我在所有机器上从 TortoiseSVN 1 6 升级到 1 8 4 我的主开发机器开始出现此错误 ra serf An error occurred during SSL
  • 具有任意属性的 SPARQL 属性路径查询

    SPARQL 属性路径 http www w3 org TR sparql11 query propertypaths任意长度的查询需要使用特定的属性 我想查询并查找从一个资源开始并以另一个资源结束的任何路径 例如 SELECT p WHE
  • 如何 Iterator::chain 迭代器向量?

    对于给定的一组迭代器 a b c 可以使用以下命令成功链接它们a chain b chain c 由于我尝试编写的 CLI 实用程序提供了路径向量 字符串 dirs a b c d e f 我想使用walkd dir在它们每个上 然后将它们
  • 更改node_modules位置

    有没有办法更改node modules文件夹位置 例如 dir1 dir2 node modules to dir1 dir2 node modules 以下是查看的代码node modules默认文件夹 Module prototype
  • 动作和动作监听器之间的区别

    有什么区别action and actionListener 我应该什么时候使用action versus actionListener 动作监听器 Use actionListener如果你想要一个钩子before真正的业务行动得到执行
  • 使用 Spring Security 进行单元测试

    我的公司一直在评估 Spring MVC 以确定我们是否应该在下一个项目中使用它 到目前为止 我喜欢我所看到的 现在我正在研究 Spring Security 模块 以确定它是否是我们可以 应该使用的东西 我们的安全要求非常基本 用户只需提
  • 如何使用 CodeModel 初始化二维数组

    我需要初始化一个二维数组 如下所示 Object someName param1 param2 param3 param4 param5 param6 我尝试过像 JExpression exp JExpr newArray codeMod
  • 多用户角色环回

    我正在尝试使用 Loopback 作为后端来制作一个应用程序 我以前已经使用过环回 但现在我想做一些我以前从未做过的事情 我想要的很简单 我将有 3 种类型的用户 管理员 服务者和默认用户 但是 我需要限制每种类型用户的访问控制 管理员可以
  • Rust 从 fn 返回结果错误:类型不匹配

    我希望这个函数返回一个错误结果 fn get result gt Result
  • 对图像进行积分的有效方法

    我有一个 2D 数组 典型大小约为 400x100 如图所示 它看起来像一个梯形 因为右下角的元素是 nan 对于数组中的每个元素 我想对多个元素 大约 10 个元素 沿列执行数值积分 在物理语言中 将颜色视为力的大小 我想找到通过计算 F
  • Material Design lite sidenav onhide 仅显示图标

    我正在尝试制作一个侧导航 当切换时 它不会完全隐藏侧导航 并会显示代表每个选项卡的图标 我的代码在这里 header mdl layout drawer border right 0 header mdl layout drawer mdl
  • 脚本通过 CentOS 安装 mysql-server,无需密码提示

    我的操作系统是 CentOS 6 6 我想知道如何通过 shell 脚本自动安装 mysql server 我发现有一个主题讨论了同样的问题 但在 CentOS 6 上失败了 ubuntu安装mysql无密码提示 https stackov
  • 长时间运行任务的视觉反馈

    我有一个长时间运行的 for each 循环 并且想知道是否有一种惯用的方法来添加一些视觉用户反馈 以便用户不会认为应用程序崩溃了 private void btnRunLongRunningTask Click object sender
  • Hazelcast Jet 查询

    我对 Hazelcast Jet 有以下疑问 用例如下 有一个应用程序 应用程序 A 部署在集群中 使用 Hazelcast IMDG 并将数百万条记录 事务放入 hazelcast IMap 中 已为此 IMap 配置事件日志 还有另一个
  • 如何获取 SwiftUI 中 TextEditor 的光标位置?

    因此 在我的文本编辑器中 我想知道光标的几何位置 我还计划在该位置之后附加一些文本 那么我该怎么做呢 好吧 所以我想出了一个方法来做到这一点 首先 我创建了一个struct存储光标位置 import foundation struct Cu
  • Docker - Node.js + MongoDB - “错误:无法连接到 [localhost:27017]”

    我正在尝试为我的容器创建一个容器Node应用程序 这个应用程序使用MongoDB以确保一些数据的持久性 所以我创建了这个Dockerfile FROM ubuntu latest Installing MongoDB Add 10gen o
  • 如何在第三方库中的Eclipse中设置断点?

    我在第三方库的类中收到 NullPointerException 现在我想调试整个事情 我需要知道该类是从哪个对象中保存的 但在我看来 我无法在第三方的班级中设置断点 有谁知道摆脱我的麻烦的方法吗 当然 我使用 Eclipse 作为我的 I
  • C# Networkstream.read()

    read buffer offset length 实际上是如何工作的 如果我将读取的长度传递为 32 这是否意味着它会一直阻塞 直到收到 32 个字节 我知道如果出现套接字异常或连接关闭 它将分别返回异常或 0 如果发送方只发送 31 个
  • 如何使用 Rspec 测试 google Analytics (garb) API?

    我正在使用garb gem https github com vigetlabs garb从 Google Analytics 中获取一些基本统计数据 例如页面浏览量 一切正常 但我无法找出测试 API 调用的最佳方法 这是我的 Analy
  • 如何计算提交、树和 blob 的哈希值?

    我对如何计算提交 树和 blob 的 SHA 1 哈希值感到困惑 按照本文 https gist github com masak 2415865 提交哈希值是根据以下因素计算的 提交的源树 分解为所有子树和 blob 父提交 sha1 作