【问题标题】:Can someone check I changed the attributes of past git commits?有人可以检查我更改了过去 git 提交的属性吗?
【发布时间】:2021-10-19 00:11:53
【问题描述】:

我需要创建一个 GitHub 存储库,其中每个提交都有较早的日期。我的意思是我更改了本地计算机的日期时间(到过去的日期),编写了一些代码,然后使用该日期提交和推送。然后,我可以在我的 GitHub 存储库中看到,出现的提交日期是我提交和推送时本地计算机中的假日期。

我的问题是:有人可以通过某种方式验证我确实伪造了这些日期吗?我还删除了一些提交和推送(使用git reset)并使用git amend 更改了提交的作者姓名。有什么方法可以验证我做了这些更改吗?

据我所知,git log 是人们可以查看每个提交的作者和日期的少数几种方式之一(我已成功更改),但有什么方法可以让他们拥有回购的更改历史?

【问题讨论】:

    标签: git github repository repo


    【解决方案1】:

    警告其他阅读此问题的人:更改代码库的 git 历史记录并非没有注意事项,尤其是在其他开发人员也在使用它的情况下。因此,如果您有充分的理由更改提交作者/日期,请确保您的开发人员在这件事上保持一致。

    关于 git 历史

    如果其他开发人员在本地签出相同的代码库,并且他们提取了您的更改,他们很可能会注意到相互冲突的历史记录。

    例如,假设我覆盖了最后一次提交,并将作者从其他人更改为我自己:

    git commit --amend --reset-author
    git push -f
    

    当另一个开发者拉取时,他们会遇到合并冲突。
    他们的 Vim(或其他配置的编辑器)将打开,并询问他们是否要合并。如果它们确实合并,则此消息将是 git 输出到终端的(部分):

     + ed36af4...fbe3f7f main       -> origin/main  (forced update)
    

    如果没有人检出被篡改的分支,那么任何人都不太可能注意到历史记录的变化。

    找出篡改的其他方法

    上面,我正在处理一些侦探工作。举一个人为的例子,如果你将提交日期更改为 git 发明之前,那么人们就会知道 git 历史记录已被篡改。作为一个不太人为的例子,如果您更改 git 作者,使他们无法访问该存储库,那么这将是篡改的证据。 (“呃,Sara 2017 年没在这里工作,她怎么会访问这个私人仓库?!”

    请注意,除了 git 历史记录之外,还有其他方法可以保护/监控/审核 repos。如何实现这一点是另一个问题的另一个主题。但是一个非常简单的方法是定期备份 git repos。

    【讨论】:

      【解决方案2】:

      以下是要知道的:

      • commit 是一个编号实体,由数据(源快照)和元数据(作者姓名、电子邮件和日期戳、提交者三元组、父哈希 ID、任何其他内部标题、parent 行等,然后是一个空行和提交消息主题和正文)。

      • 数据(源快照)实际上存储为单个元数据行,tree <em>hash-id</em>。因此,源快照是间接的,这就是存储 same 源快照的两个提交实际上并不两次存储源快照的方式。例如,如果您使用树 T1 进行提交 C1,然后创建具有新树的新提交 C2,然后将提交 C2 还原为提交 C3,则提交 C3 中的树与 C1 中的树相同。

      • 提交的哈希 ID 是(整个)元数据的加密校验和,包括附加到消息正文的任何​​提交签名。有关更多详细信息,请参阅How does commit signing work?

      • 目前,此加密校验和使用 SHA-1,即has been broken。然而,破解 SHA-1 的现有技术成本高昂(以美元计,或无论您的当地货币是什么,以及计算时间)并且留下明显的痕迹。

      每当有人进行提交时,他们控制所有元数据,因此无法判断新提交是否包含准确的元数据(“是的,我的名字真的是 Zaphod Beeblebrox,我今天早上合法地改变了它”)或没有(“我撒谎了,我的法定名字实际上是 Jean Baptiste Emmanuel Zorg”)。但是,如果有人要接受现有的提交并尝试修改它,他们将得到的不是修改后的提交,而是另一个 新的提交,具有新的和不同的 SHA-1 哈希 ID。获得重新使用旧哈希 ID 的新提交的唯一方法是使用 SHA-1 破坏技术,这会留下明显的痕迹。

      提交自己历史,并形成一种Merkle Tree,因为每个提交都持有其父提交的哈希ID。只是我们(人类)和 Git 本身通常find 使用一个分支名称,它被定义为一个名称1 持有一个可变的哈希 ID。只要有人有权在该名称中存储新的不同哈希 ID,如果我们信任 name,我们就会看到最新的哈希 ID。

      这反过来意味着,如果你真正注意/使用哈希 ID,而不是简单地依赖于一些可变的分支名称,你会注意到任何人“摆弄历史”,无论它在物理上是否引人注目(即,您必须有一些提交 X 才能看到其他人提出了一些不同的哈希 ID Y 来代替 X,然后由于 Merkle-tree 问题,还更改了每个后续提交)。

      Git 标签也可以被签名(使用 GPG 签名或等效的)。这些数字签名方法——无论是用于单个提交,还是仅用于一系列提交结束时的标签——都可以使用比 SHA-1 更安全的加密技术。 Git 本身也被修改为使用 SHA-256,如果没有别的,它至少有更多的,这使得用于破坏 SHA-1 的技术不太有效。


      1具体来说,分支名称refs/heads/<em>branch</em>形式的名称。前导 refs/heads/ 部分使其成为分支名称。如果前导部分为refs/tags/,则名称为标签名称。其他名称位于 refs/ 名称空间的不同部分。特殊名称(HEADORIG_HEADMERGE_HEAD 等)位于其他必需的顶级 refs/ 限定符之外。

      【讨论】:

        猜你喜欢
        • 2021-10-16
        • 1970-01-01
        • 2018-12-07
        • 2017-06-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-24
        • 1970-01-01
        相关资源
        最近更新 更多