git 如何确保相同操作/数据的提交 SHA 密钥仍然是唯一的?

2023-11-24

如果我创建一个文件foo with touch foo然后运行shasum foo它会打印出来

da39a3ee5e6b4b0d3255bfef95601890afd80709.

无论我跑多少次shasum foo或者如果我在另一台计算机上运行它它总是会打印da39a3ee5e6b4b0d3255bfef95601890afd80709因为,是的,它是完全相同内容的 SHA1 表示形式。在这种情况下内容为空:)

但是,如果我执行以下步骤:

cd /some/where
mkdir demo
git init
touch foo
git add -A
git commit -m "adding foo"

..并记住 SHA 密钥commit (e.g. 959c363ed4cf147725360532454bc258c964c744).

现在,当我删除demo并重复完全相同的步骤,仍然是commitSHA 密钥会有所不同。这很好,重要的是要确保identity.

但我想知道的是,git 究竟做了什么来确保提交哈希值始终是唯一的,即使它们对完全相同的内容执行完全相同的操作。 git 是否简单地使用类似的东西uuidgen为提交对象生成唯一的 id,或者它是否根据时间戳、您的 mac 地址、您的 wifi 信号等的组合执行不同的操作。


但我想知道的是,git 究竟做了什么来确保提交哈希值始终是唯一的,即使它们对完全相同的内容执行完全相同的操作。

没有什么。如果您创建相同的内容,您将获得相同的 SHA-1。

First, however, you need to realize that "same contents" of a commit means that—provided you don't get an accidental SHA-1 collision1 or find a way to break SHA-1—you must create the same complete repository history leading up to and including the commit itself, including all the same trees, author-names, time-stamps, and so on.

这是因为提交的内容are如果你跑步你会看到什么git cat-file -p <sha-1>在提交上(加上标记和大小字段,表示“此对象属于提交类型”,因此没有简单的方法可以通过创建与先前提交内容相同的 blob 来破坏事物)。这是一个例子:

$ git cat-file -p 996b0fdbb4ff63bfd880b3901f054139c95611cf
tree e760f781f2c997fd1d26f2779ac00d42ca93f534
parent 6da748a7cebe3911448fabf9426f81c9df9ec54f
parent 740c281d21ef5b27f6f1b942a4f2fc20f51e8c7e
author Junio C Hamano <[email protected]> 1406140600 -0700
committer Junio C Hamano <[email protected]> 1406140600 -0700

Sync with v2.0.3

* maint:
  Git 2.0.3
  .mailmap: combine Stefan Beller's emails
  git.1: switch homepage for stats

请注意,此字符串包括树及其 SHA-1、此提交的父 SHA-1、作者和时间戳、提交者和时间戳以及消息。如果你改变哪怕一个一位的这一点 - 例如通过尝试更改底层树,或使用一些不同的父提交 - 您将得到一个新的、不同的 SHA-1,而不是996b0fdbb4ff63bfd880b3901f054139c95611cf.

所以这个问题的答案是:

因此,理论上,如果我和您在完全相同的时间使用完全相同的配置作者、电子邮件等执行完全相同的步骤,我们实际上会获得相同的提交 SHA 密钥吗?

is "yes". However ... you must start with the same staging area (this is what will become the tree), and the same parent commits. If you then configure your author, email, etc., exactly the same as the other guy, and both of you create a new commit at the same second (or using git's environment variables2 to force the time stamps), you both get the same new commit.

这正是我们想要的。当你被命名为“我”时,你创建它,或者当我被命名为“我”时,我创建它,如果所有其余内容都相同,那么这并不重要。因为无论谁创造了它,另一个“我”都可以克隆它,然后我们都可以拥有相同的东西。

(如果我想确保创造某些东西的“我”不会与真实的我混淆,我需要添加一些独特的东西,我知道而另一个我不知道。当然,如果我在某个地方发布这个东西,我认识的其他人都知道。但这就是签名、注释标签的用途。它们可以包含 GPG 签名。)


1The chances of an accidental hash collision (for any pair of objects; chances rise with more objects) are 1 out of 2160, which is ... very small. :-) The rise is actually very rapid, so that by the time you have a million objects, it's about 1 out of 2121. The formula I use here is:

1 - 指数(((-(n * (n-1))) / (2 *r))

where r = 2160 and n is the number of objects. Without the subtraction from 1, the equation calculates the "safety margin", as it were: the chance that we won't have an accidental hash collision. If we want to keep this number in the same range as the safety margin that a disk drive won't read back the wrong contents for a file—or at least, that disk-makers claim—we need to keep it around 10-18, which means we need to avoid putting more than about 1.7 quadrillion (1.7E15) objects in our git databases.

2There are many git environment variables that you can set to override various defaults. The ones for the author and committer, including date and email, are:

  • GIT_AUTHOR_NAME
  • GIT_AUTHOR_EMAIL
  • GIT_AUTHOR_DATE
  • GIT_COMMITTER_NAME
  • GIT_COMMITTER_EMAIL
  • GIT_COMMITTER_DATE
  • EMAIL

如中所述git 提交树文档.

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

git 如何确保相同操作/数据的提交 SHA 密钥仍然是唯一的? 的相关文章

  • git 如何在不同分支中保持不同的配置文件?

    请允许我先表达一下我的尝试 假设我有两个分支 Alice1 和 Alice2 Alice1 有自己的服务器 Alice2 也有自己的服务器 我希望能够签出 Alice1 编写我的代码 然后通过使用保存在 URL 配置文件中的 URL 直接推
  • 克隆/推送 Git Repos 时出错 443:访问错误,但未使用代理

    当使用 git 远程存储库进行这些操作克隆 推送时 我遇到了非常奇怪的问题 假设我正在尝试将更改推送到远程存储库 git push origin master 然后我会得到这个错误 致命 无法访问 Remote Repo 无法连接到 git
  • 删除 git Branch -a 列出的分支

    命令git branch a列出了一堆不在存储库上且不在本地分支上的分支 这些怎样才能删除呢 develop master remotes origin cloner 例如 remotes origin cloner曾经存在于存储库中 但它
  • 读取 git 的最后一次提交和提交号

    在使用Git源代码的maven项目中 每当我使用maven编译构建时 是否可以读取git的最后一次提交和提交号 我想使用该提交编号来找到最后一次提交 这是假设您想要读取该信息 然后将其存储在属性文件中 基于https github com
  • Gitlab-runner 更改 builds_dir

    我在生产服务器上的默认 builds dir 是 root builds qL8eZYTH 0 faramarzqoshchi testing gitlab runner 我希望它是这样的 home domain name public h
  • 在 Git 中查看已删除的文件

    我已使用 Git 删除了一个文件 然后又提交了 因此该文件不再位于我的工作副本中 我想查看该文件的内容 但不想真正恢复它 我怎样才能做到这一点 git show HEAD path to file 您可以使用显式提交标识符或HEAD n查看
  • 如何更改我的 Github Pages 默认 index.html 位置?

    我已经尝试过以下线程中显示的内容 我可以将我的 Github Pages index html 放在存储库的子文件夹中吗 https stackoverflow com questions 25320356 can i have my gi
  • 如何在提交后删除本地 git 历史记录?

    我想从 Dropbox 切换到开源 Sparkleshare 它使用 git 进行同步和版本控制 如果说我在文件夹中删除了一个 1GB 文件 它会保留在本地 git 文件夹的历史记录中 但我希望将这种大量数据放在服务器上而不是客户端上 如何
  • 如何在 *Windows* 中将 Mercurial 存储库转换为 Git? [复制]

    这个问题在这里已经有答案了 可能的重复 在 Windows 上将 Mercurial hg 存储库转换为 Git 7 https stackoverflow com questions 3267232 converting a mercur
  • Git:切换工作区(计算机)而不提交

    有没有办法在不进行提交 签出的情况下应用差异补丁或类似补丁 我的情况 我工作时经常在计算机之间切换 我的提交历史有一堆 开关机 消息 我最初的猜测是这可能会导致其他麻烦 但我想我可能会问是否有适合这种情况的合适的解决方案或工作流程 编辑 澄
  • 压缩 git log --graph 输出?

    有没有办法压缩输出git log graph那么它会在视觉上压缩遵循线性历史的提交吗 基本上 我只想查看图中某些分支分歧 合并的点 以获得我的分支结构的顶层 概述 举个例子 如果我有这个 A Z H B G C F D E 我希望它显示类似
  • Visual Studio 2010 中的源代码控制?

    在对 SO Google 和 MSDN 论坛进行了一些搜索之后 我感到很沮丧 因为对于一个看似显而易见的问题 甚至可能是一个愚蠢的问题 信息太少 我需要在 Visual Studio 2010 Professional 中使用源代码管理 我
  • 从另一个分支或从 master 创建 Git 分支?

    所以我是 Git 新手 我最近从存储库中提取了主分支的新版本 我创建了一个branch 1 获取某个功能并将其推送到存储库并创建拉取请求 现在我创建了一个新的branch 2 具有另一个功能 但由于我的拉取请求尚未合并 再次拉取 maste
  • 哪些Git命令无法在本地执行?

    当我和同事谈论 Git 时 我告诉他们 一旦本地存储库初始化 只有三个 Git 命令不能在不访问远程存储库的情况下执行 假设origin当然 不在本地计算机上 git fetch http www kernel org pub softwa
  • 如何在 Mac OS X 10.9 上安装和使用最新的 Git?

    我从 sourceforge 下载了 Git 2 4 3http git scm com download mac http git scm com download mac对于我的 Macbook Pro OS X 10 9 5 然后安装
  • 如何为Git存储库组织和设置镜像备份服务器?

    我正在将一些 svn 存储库移至 Git 所以 我基本上尝试做的是 设置一台带有裸 Git 存储库的服务器 我将从中拉取和推送到该存储库 为第一台服务器上的所有存储库设置一些备份服务器 所以 假设我的服务器上有一个目录 例如 HOME gi
  • MySql 5.7 函数 UUID() 默认排序规则 - 非法混合排序规则

    Problem MySQL uuid 默认排序规则与配置连接排序规则不进行比较 我有一个使用字符集创建的数据库 表 字段 utf 8和排序规则utf8 polish ci my cnf 如下 init connect SET NAMES u
  • git pull origin master 返回致命错误:无效的 refspec

    问题是这样的 每当我这样做时 git pull https github com username reponame github io git 接下来是网址 我没有遇到任何问题 但是当我这样做时 git pull origin maste
  • 无法重新索引 magento 1.7.0.2 卡在“处理”上

    我的 magento 索引中有九分之七停留在 处理 状态 我需要重新索引它们才能正确显示我的网站 我通过 ftp 访问我的 var locks 并删除其中的两个文件 但是当我刷新索引页时 它们只是重新出现 index process 3 l
  • Gitflow错误无法初始化

    我已经将 gitflow 安装在我的 github 项目所在的目录中 但是 当我尝试使用命令 启动时git flow init 我收到以下错误消息 git flow init C cygwin64 usr local bin gitflow

随机推荐

  • onDestroy之后是否可以调用回调方法?

    在我的应用程序的最新版本中 一些用户遇到了我无法重现的崩溃 目前仅Samsung设备运行Lollipop遇到这个问题 但这可能只是巧合 在分析了堆栈跟踪和相关代码之后 我想我可能已经找到了罪魁祸首 为了测试我的假设 我将代码简化为下面的代码
  • 编写供国际使用的软件的最佳实践 (i18n)

    我正在寻求编写过国际通用软件的专家的意见 我想了解人们在每个逻辑软件层 数据 rdbms 业务 中间件 用户界面 所采用的最佳实践 谢谢你提供的所有帮助 Data 当您使用 UTF 8 时 请做好每个字符最多占用 3 个字节的准备 对于中文
  • 在 PyQt 中启动 new QThread() 时传递参数

    我有一个用 Python 编写的多线程应用程序 其中一个线程 照顾 GUI 另一个线程是工作线程 但是 工作线程有两个主要函数 或者说两个主要作业 我需要告诉运行函数到底要执行哪个作业 所以我的想法是在工作线程中创建一个运行函数 该函数将采
  • 如何从命令行获取 CSRF 令牌?

    我经常使用测试我的应用程序curl过去我不得不简单地用以下内容来概括我的观点csrf exempt 我真的不想这样做 因为我有一种讨厌的感觉 我会忘记在部署中这样做并享受一生的 CSRF 地狱 有没有办法让我使用 Django 的 shel
  • gnu 排序的意外结果

    当我尝试对以下文本文件 输入 进行排序时 test1 3 test3 2 test 4 用命令 sort input 输出正是输入 这是输出 od bc input 0000000 164 145 163 164 061 011 063 0
  • 以 2 的补码表示十六进制值

    我有一个字符串十六进制值 我需要用 2 的补码来表达它 string hx FF00 我所做的是将其转换为二进制 string h Convert ToString Convert ToInt32 hx 16 2 然后反转它 但我无法使用N
  • HttpContext.Current.User!= HttpContext.User?

    Is HttpContext Current User在全局 asax 中不一样HttpContext User在行动方法中 我为用户分配了一些角色 但他们似乎迷失了 下面的代码显示了正在发生的情况 当用户登录时 两个断言都会被命中 首先是
  • 在组件编辑器中获取字段的_当前_值? (Tridion 2011 SP1)

    我正在编写 保存 命令的扩展 基本上我想验证某些字段并显示一个弹出窗口 允许编辑器根据当前日期 发布号和一些其他属性选择给定的关键字或其他值 我以为我取得了很好的进步 直到我最终发现 display getItem 返回存储在 CM 中的项
  • 如何获取传递给函数的变量的名称?

    让我用下面的例子来解释我的问题 public string ExampleFunction string Variable return something string WhatIsMyName Hello World string He
  • 从 Jupyter 笔记本中删除空行

    有没有一种简单的方法可以从 IPython 笔记本中删除空行 我在网络开发中养成了留空行的习惯 而且我的手指往往会自动按回车键 这使得 IPython 笔记本变得更少 因为占用了我的 14 英寸屏幕的太多空间 并且在大多数情况下并不更具可读
  • 仅当参数不是常量时,math.h 中的 sqrt 才会导致链接器错误“未定义对 sqrt 的引用”

    我创建了一个小程序 如下 include
  • android 以编程方式清除日志

    我想在按下按钮来分析我们应用程序的某些部分 计算一些内容 后获取整个日志 Log d 我可以通过以下代码来做到这一点 HashMap
  • Google 容器引擎中的自动缩放

    据我了解 容器引擎目前处于 alpha 阶段 尚未完成 从文档中我假设 Pod 还没有自动缩放 例如 取决于 CPU 负载 对吗 我希望能够配置一个复制控制器 以便在平均 CPU 负载达到定义的阈值时自动添加 Pod 和 VM 实例 这是近
  • 如何避免 ViewModel 中的命令混乱?

    我正在构建一个使用相当多命令的应用程序 它们使我的视图模型变得混乱 MVVM 对我来说是新的 如果这个问题有点愚蠢 我很抱歉 有没有办法减少混乱 例如 在这里您可以看到杂乱的一部分 private void InitializeComman
  • 获取推送通知的设备令牌

    我正在研究推送通知 我编写了以下代码来获取设备令牌 BOOL application UIApplication application didFinishLaunchingWithOptions NSDictionary launchOp
  • WebGL:尽管使用相同的代码,一切都很模糊

    刚开始使用 WebGL 尝试绘制一些基本线条 甚至不是多边形 我找到了一些例子 将它们复制粘贴到本地并在 Firefox 中运行它们 它们看起来不错 锐利 清晰的边缘 然后 我创建自己的项目 重构 糟糕 示例代码 使用 RequireJS
  • HighCharts通过ajax加载数据

    在过去的几天里 我在使用 Highcharts 库填充来自 api 的一些示例 json 数据中的 ajax 时遇到了问题 我尝试在我的ajax回调中使用chart series 0 data json和类似的东西 但没有任何效果 我的 j
  • getCompatedStyle 给出“透明”而不是实际的背景颜色

    这是一个惊喜 以下代码似乎没有给我屏幕上的实际颜色 h1 document querySelector h1 window getComputedStyle h1 color Gives rgb 0 0 0 我认为这是正确的 然而 wind
  • 如何在实体框架6中调用存储过程(代码优先)?

    我对 Entity Framework 6 非常陌生 我想在我的项目中实现存储过程 我有一个存储过程如下 ALTER PROCEDURE dbo insert department Name varchar 100 AS BEGIN INS
  • git 如何确保相同操作/数据的提交 SHA 密钥仍然是唯一的?

    如果我创建一个文件foo with touch foo然后运行shasum foo它会打印出来 da39a3ee5e6b4b0d3255bfef95601890afd80709 无论我跑多少次shasum foo或者如果我在另一台计算机上运