有一天,我正在使用Git(我仍在使用它),而在提交时,电力中断了。
当我(实际上是电力)回来时,git repo损坏了。我不记得确切的名字了,但这是“无效的引用”之类的东西。
很容易猜到该提交在操作过程中被破坏了(我是通过IntelliJ提交的,它会自动进行索引添加)。也很容易猜到,实际上,“提交”不像具有相同名称的DBMS操作那样具有ACID。
问:有没有办法确保回购变更操作尊重原子性?即,如果电力再次下降,并且我要提交,我希望我的文件系统不处于损坏状态。
有一天,我正在使用Git(我仍在使用它),而在提交时,电力中断了。
当我(实际上是电力)回来时,git repo损坏了。我不记得确切的名字了,但这是“无效的引用”之类的东西。
很容易猜到该提交在操作过程中被破坏了(我是通过IntelliJ提交的,它会自动进行索引添加)。也很容易猜到,实际上,“提交”不像具有相同名称的DBMS操作那样具有ACID。
问:有没有办法确保回购变更操作尊重原子性?即,如果电力再次下降,并且我要提交,我希望我的文件系统不处于损坏状态。
Answers:
我不知道是否有一种方法可以使Git提交在完全定时的电源故障中幸免,但是您也许可以修复您的存储库。
Git对象应该是不可变的,因此所有较早的提交仍应有效。根据此答案,您可以更改哈希值,.git/refs/heads/<branch-name>
以将正在处理的分支的标题更改为上一个提交(您可以在中看到它们.git/logs/HEAD
)。
对该答案的评论说,此方法“仍然使存储库处于损坏状态,但这可以恢复它”。我没有对此进行测试(不知道如何复制您的情况),但是我假设恢复是通过完成的git gc
,它将删除损坏的提交。
Git的存储系统不是事务性的,因此,硬件问题肯定有可能使事物处于不一致状态。另一方面,Git的运行速度也非常快,因此您一定很不幸被“电源故障”类型的问题所困扰(磁盘的系统性问题是其他问题)。速度之所以如此,部分原因在于它不是事务性的。事务确实非常昂贵,因为它们必须等待磁盘确认已写入数据。(数据库做了各种各样的事情来试图掩盖这笔费用,但是最终它们还是要付出代价。一些竞争对手的DVCS 是事务性的,是的,在与git相同的硬件上,它们要慢得多。)
在最坏的情况-共灾难性的磁盘故障(这是我见过的发生) -对于任何DVCS恢复的唯一方法是使用的事实,它是分布式。如果您直到最近才将更改推送到另一个系统,并且它们已将其共享给许多不同的主机,则恢复只是将这些其他位置之一用作工件来源,即从(即使只是暂时的)。这样,您就可以回顾有趣分支的历史,并且可以很快重新开始工作。一次清除掉您的存储库的许多分布式副本的任何事情,要么是一种灾难,您不必担心以后进行编程(想想陨石的严重影响),要么是彻底的敌人行动。(尽量不要让这些敌人成为敌人……)这与非分布式系统形成了鲜明的对比,在非分布式系统中,丢失托管所有内容的中央服务器是致命的打击。