如何破坏一个Git仓库?

9
有哪些方法可以创建一个损坏的git仓库?有没有一些有趣的方法可以永久性地破坏git仓库?你能够使git仓库处于一种“正常但奇怪”的状态吗?
我的兴趣来自于当某人担心他们是否真正创建了一个无法恢复的状态时。通常情况下,这很容易修复或者至少拼凑起来。在git中有隐藏的(邪恶)功能吗?

4
随机选择100个8位数字。将其中一个数字与.git目录下每个文件的每个字节进行异或运算。然后忘记选定的随机数字。 - ta.speot.is
我似乎记得在将Git存储库放入Dropbox文件夹时遇到了问题——当Git尝试写入正在上传的文件时,会出现竞争条件。不确定它们的性质是什么,无论是非明显的损坏还是失败的提交,但您可能需要调查一下。 - millimoose
步骤一:不要使用ECC内存。步骤二:???。http://www.mail-archive.com/git@vger.kernel.org/msg37928.html - Edward Thomson
@ta.speot.is - 尽管在.git中加密所有内容听起来很有趣,但实际上却缺乏吸引力。我刚刚这样做了,所有的git status都报告了fatal: Not a git repository (or any of the parent directories): .git,这与在任何其他目录中运行status是相同的。 - Kyle Kelley
1个回答

7

好的,最直接的腐败可能发生在.git/objects目录内部的数据或数据完整性丢失。由于它被设计为不可变的、只写的存储机制,一旦你违反了这个假设,很多其他的东西就会崩溃。最常见的情况是网络传输中损坏的packfiles。除非你非常(读作:天文数字级别)倒霉,否则Git会自动检测到并大声抱怨。要以这种方式获得静默失败,你需要以这样一种方式破坏blob,即使在deflate压缩下也能保留其SHA1哈希值...具有准确的类型和大小头。

因此,git在验证自己的数据完整性方面表现得非常出色。我们还能做什么呢?要使状态真正无法恢复,你需要:

  1. 与该状态相关的提交和其他对象未被引用(也就是说,在.git/refs或任何reflog下没有任何命名引用),然后
  2. 进行垃圾回收以永久删除状态,或者获取一个新的克隆并删除原始克隆。
否则,您总是可以运行git checkout <sha> && git branch recovered并获得所有工作的备份,无论您做了什么。在正常的git使用中,当您进行rebase、cherry-pick或filter-branch操作时,提交会变成孤儿,所有这些操作都是基于旧提交对象创建新提交对象的,或者如果您在分支周围执行git reset --hard。默认情况下,您有大约两周的宽限期,然后它们将被删除,尽管您始终可以截断您的reflog并手动清理以提前销毁某些内容。
更多的情况是,我看到用户在第一次没有将其数据添加到git中时发生数据丢失。新用户有时会犹豫不决地频繁提交,并尝试使用带有脏工作副本的命令。如果您从未在git中记录状态,则git无法为您恢复它!
如果你可以接受“可恢复但难以察觉”的欺骗,你可以使用git replacegraft points进行一些恶意操作,以欺骗git在虚假历史上进行合并或筛选分支操作。替换的提交仍然被视为可达,因此它不会造成永久性损害。

1
新用户有时会犹豫不决地提交。我一直告诉大家,提交是免费的。 - ta.speot.is
1
@ta.speot.is:这是一个难以适应的心理调整!我通常尝试将其呈现为git具有两个独立的操作:“commit”用于记录状态,“push”用于共享状态。即使人们在理性上理解它,习惯也是最难改变的东西。 - Ash Wilson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接