Git- 修改 .git refs 目录中的提交数据有什么危险



我创建了一个 git 存储库来测试一些 git 功能。我从一篇博客文章中了解到,分支存储在.git/refs/heads/文件名是应用程序中分支的名称,每个文件都包含分支指向的提交 sha。

事实证明,您可以将提交 sha 替换为.git存储库中存在的任何提交 sha。当我这样做并且它起作用时,我对自己说这真的很错误,我不应该这样做,但我只能想到涉及人为错误。所以我的问题有点双重。

  1. 替换 git 分支/引用文件中的提交 sha 有哪些危险?

  2. 是否有想要直接修改.git文件夹中的分支文件的情况?而不是使用 git 命令来执行这些行为。

Git 改变这些事情的方式在未来有很大的风险。 这并非特别不可能,因为 Windows 上的 Git 存在分支名称大小写问题,例如,分支名称aA在 Linux 和 Git 中是两个不同的分支名称,但存储在 Windows 上的同一文件中。 当分支名称打包(存储在.git/packed-refs中 - 查看文件以查看时,尤其是在运行git gc之后),这两个分支在Windows上也是不同的。 当分支名称解压缩时,两个分支名称合二为一,后果相当混乱。

除了未来的风险之外,将原始哈希 ID 转储到.git/refs/heads/branchname文件中的最大危险是您可能会弄错:它可能是伪造的哈希 ID,也可能是不是提交对象的对象的哈希 ID。 Git 的正常操作不允许这些,因此 Git 的各种内部位可能会假定分支文件内容是指向提交对象的有效哈希 ID。

否则,这正是git reset --softcommit-specifierHEAD附加到的任何分支名称所做的,也正是git branch -fnamecommit-specifier对未附加HEAD的分支名称所做的。 因此,如果您的目标是在不使用该命令的情况下模拟这两个命令之一,您可以这样做(至少在今天,直到 Git 对 Windows 和类似操作系统上的名称大小写问题做一些事情)。

至于这个:

是否有想要直接修改.git文件夹中的分支文件的情况?

它对于实验很有用(例如,测试对 Git 的源代码更改,如果您想查看是否已修复分支名称中包含无效哈希 ID 时发生的一些崩溃)。 如果 Git 自己的内部安排已损坏,则在系统崩溃后偶尔可能会很有用。

替换 git 分支/引用文件中的提交 sha 有哪些危险?

git gc可以删除您不希望删除的内容。 我忘记了确切的规则(无论如何它们将来可能会更改),但简短的版本是无法访问的对象(blob、树和提交)可以不可撤销地删除。 如果分支指向的哈希使提交树的大部分无法访问,您可能会发现自己永久丢失了该数据。

是否有想要直接修改.git文件夹中的分支文件的情况?而不是使用 git 命令来执行这些行为。

我不知道,但 git 在设计时考虑了 Unix 哲学:它不会阻止你做愚蠢的事情,因为这可能会阻止你做聪明的事情。

它没有真正的危险。你注定能够看到 git 的幕后。最大的潜在问题是,如果该头指向的提交无法以任何其他方式访问,并且您将其替换为其他内容,那么您可能无法找到旧数据,并且最终将被删除。但是有很多东西(reflog,远程存储库)可以使您免于这种情况。知道如何手动执行操作并没有什么坏处,以防您最终得到一些工具不想使用的不一致状态的存储库,并且您需要尝试恢复。

  1. 在 git 分支/ref 文件中替换提交 sha 有哪些危险?

直接修改.git/refs/heads/中的文件应该没问题,但据我所知,不能保证这将保持不变。也没有什么可说的.git/refs/heads/包含所有甚至任何分支引用 - 它们也可以驻留在包文件中。您可能已经知道,您最好使用内置工具来更新引用。参见 git update-ref, git symbolic-ref。

  1. 是否有直接修改 .git 文件夹中的分支文件的情况?而不是使用 git 命令来执行这些行为。

不,除了测试 Git 本身的行为之外,我想不出任何理由。如果需要修改它们,Git 提供了足够的工具来安全地执行此操作。您可以使用自定义引用将任意数据保留在存储库中。Git Notes 就是这种用法的一个例子,后来它被纳入了标准工具。

最新更新