如何计算提交、树和 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 的哈希值? 的相关文章

  • `git add --patch` 和 `--word-diff`

    git add patch提供了一个很好的界面 用于检查未暂存的更改 然后仅暂存下一次提交中需要的更改 很好 除了一件事 没有明显的方法来选择哪个diff视图来使用 特别是 我希望能够配置git add patch以同样的方式向我呈现差异g
  • 为什么 git mergetool 说“没有文件需要合并”?

    我正在尝试将 BeyondCompare4 配置为 git 中的 difftool 和 mergetool 我使用的是 git 版本 2 5 0 windows 1 到目前为止 BeyondCompare4 作为 difftool 工作得很
  • 使用脚本检查 git 分支是否领先于另一个分支

    I have branch1 and branch2我想要某种 git branch1 isahead branch2 这将显示如果branch1已承诺branch2没有 也可能指定这些提交 我无法检查差异原因branch2 is在之前br
  • 如何损坏 Git 存储库?

    创建损坏的 git 存储库有哪些方法 有没有有趣的方法可以永久损坏 git 存储库 你能否削弱一个 git 存储库 使其行为有些正常 但会做一些奇怪的事情 我的兴趣来自于当有人担心他们是否真的创建了不可恢复的状态时 它通常很容易修复或至少可
  • 如何为 bcrypt.hashpw 设置盐?

    salt yhnqazolr123098765 password bcrypt hashpw password salt repeatpassword bcrypt hashpw repeatpassword salt 我在第二行遇到错误
  • 如何获取第一次提交的 Git diff?

    我创建了一个存储库 在其中创建了一个文件 在文件中放入了一些内容 然后提交了该文件 现在 我想查看该提交的差异 理想情况下应该显示添加的文件以及添加到其中的行 然而 git diff HEAD HEAD回报fatal ambiguous a
  • 有关多个远程存储库的 Git 状态

    我有一个脚本 如果我忘记在 40 多个存储库中提交或推送一些代码 它会通过电子邮件向我发送提醒 在我的两个项目中 我遵循了这些帖子中的答案 其中我设置了 git push 来推送到多个存储库 从多个远程位置拉 推 https stackov
  • Python 无法在 git bash 命令行中工作

    Python 不会在 git bash Windows 中运行 当我在命令行中输入 python 时 它会将我带到一个空行 而不会像在 Powershell 中一样显示它已输入 python 2 7 10 它没有给我错误消息 但 pytho
  • 由于不存在大文件而导致 git Push 错误

    当尝试推送到 git 时 我不断得到相同的结果 Counting objects 78 done Delta compression using up to 4 threads Compressing objects 100 67 67 d
  • git for-each-ref - 按年龄过滤结果

    我正在使用以下命令here https stackoverflow com a 39251131 5812876 git for each ref format color cyan authordate format m d Y I M
  • Git守护进程克隆错误

    All 我正在按照以下指示进行操作this SO https stackoverflow com a 377293 724357答案 快速提供回购 当我跑步时git clone git ipAddr git project我得到这个输出 r
  • 如何标记单个文件?或如何下载特定文件? - 胃肠道

    我想向文件添加标签以轻松下载该文件而不是整个分支 如何下载GIT中的特定文件 我不知道有什么方法可以标记特定文件git 对于第二个问题 如何下载特定文件git 仅当您的意思是 同时下载 时 以下内容才有效in a git存储库 这就是我理解
  • 如何将普通的 Git 存储库转换为裸存储库?

    如何将 普通 Git 存储库转换为裸存储库 主要区别似乎是 在普通的 Git 存储库中 你有一个 git存储库内的文件夹 包含构成工作副本的所有相关数据和所有其他文件 在裸露的 Git 存储库中 没有工作副本和文件夹 我们称之为repo g
  • 如何使用 vim 作为“git show”编辑器?

    全部如所述如何使用 vim 作为 git log 编辑器 https stackoverflow com questions 16666009 how do i use vim as git log editor不适用于 git show
  • gitlab 上的权限被拒绝(公钥)

    我的问题是我无法从 GitLab 推送或获取 不过 我可以克隆 通过 HTTP 或通过 SSH 当我尝试推送时出现此错误 权限被拒绝 公钥 致命 无法从远程存储库读取 从我看过的所有线程中 这是我所做的 在我的计算机上设置 SSH 密钥并将
  • 从 github 中删除子项目提交

    我有两个存储库A and B 我错误地在我的机器上将仓库 B 克隆到了 A 内 我从存储库 B 中删除了所有代码 但是当我在源上从 A 推送并合并代码时 它还显示了子项目提交B在 Github 仓库上 我想从我的 master 上删除子项目
  • Git 扩展 - 无法在 Windows 上推送到网络驱动器中的 git bare 存储库

    我正在 Windows 上学习 git 我已经安装了 Git 扩展 版本 2 47 3 并使用了它 我在我的 C 单元中创建了一个裸存储库 作为中央存储库 并在硬盘中的其他任何位置创建了个人存储库 我对硬盘中的这两个存储库进行提交 推送和拉
  • 在 Web 应用程序中显示最新的提交值?

    我有一些 Rails 应用程序 我使用 Git 作为版本控制系统 我使用 GitHub 或 Beanstalk 作为存储库主机 从理论上讲 我想要做的事情非常简单 以某种方式在 Web 应用程序的页脚中显示最新的提交 ID 号 哈希值 这样
  • gitlab 请求将分支 A 合并到开发中(落后 3 次提交)我应该担心吗?

    在 gitlab 中创建合并请求时 我经常收到一条消息 请求将分支 A 合并到开发中 x 提交落后 gitlab想告诉我什么 我应该担心还是需要修复某些东西 什么 一段时间后合并请求在项目中打开时 由于其他人合并了自己的更改 您尝试合并到的
  • 在centos上设置jenkins:ssh密钥和git的问题

    经历了很多问题 但似乎没有什么能解决我的问题 或者更准确地说 我不确定我是否正确地完成了整个事情 所以这里是 已安装centos 6 3操作系统 然后我按照以下指南安装詹金斯 https wiki jenkins ci org displa

随机推荐

  • 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 作