看国外开发者如何检验并恢复损坏的git数据文件

【感谢 @刚子-廷皇 的热心翻译。如果其他朋友也有不错的原创或译文,可以尝试提交到伯乐在线。】

 

最近我提交了一分损坏的文件到资源库上,被问到数据是否可恢复。根据提出的描述开始着手调查和修复问题,我认为其他人也会对解决的过程感兴趣,或者遇到相同状况后可以帮助到你。

我开启了检查(fsck),发现问题出现在一个类上(我过去经常用 $pack $obj 命令使得输出可读,而且因为我也更倾向于他们):

 

错误的信息意味着一个字节在某一个地方混乱了,推测是类里面描述过的(因为检验和的索引和zlib都失败了)

通过阅读zlib源代码,我发现“检查不正确数据”意味着adler-32

算法检验zlib数据末端没有匹配已经增加的数据。因此通过zlib压缩数据是没有用的,因为到每次末尾都会有错误,此时我们了也解到这个crc文件不能匹配。这个出错的字节存在类文件的任何地方。

第一件事情我从packfilepull出损坏的文件。我需要知道到底它多大的类,然后我发现了下面的信息:

Show-index命令可以列出类和他们的偏移量。我们除了偏移量以外通通抛弃,然后排列,这样我们感兴趣的偏移量(这个位置是从上面fsck命令得出来的)是遵循下一个对象的偏移量。现在我们知道类文件长度是10863字节,然后我们可以抓取它:

我检查了文件的十六进制,搜索任何明显的错误(例如,一个4K大小运行中的0是文件系统冲突很好的信号)。但是所有的地方看起来都很合理。

注意到“object”文件不适合被zlib直接压缩;它本身包含git类信息头,而且是可变长度的。我们想要去掉它,所以开始直接使用zlib操作数据。你可以用你手工的方式(格式化信息的描述在Documentation/technical/pack-format.txt里面),或者你也可以用debugger搞定它。我选择了后者,创建了一个验证的包如下:# pack magic and version

然后在debugger中运行”git index-pack tmp.pack” 命令(会停在unpack_raw_entry)。做到这里,我发现有3个自己的信息头(信息头本身有一个完整的类型和大小)。然后我用下面语句去掉了这些内容:

我用一个自定义的C程序过的zlib的解压锁结果。但是它报错了,我得到准确的输出数字字节(也就是说,它匹配了上面解码的git的信息头大小)。但是”git hash-object” 命令的结果并没有相同的shal值。所以现在仍然有一些错误的字节是我不知道的。这个文件发生在C源程序代码,我希望我能注意到一些明显的错误,但是我没有成功,我甚至都编译成功了!

我也试过和在资源库相同路径下其他版本的文件作比较,希望有不一样和不合理的部分。不幸运的是,这碰巧是唯一的修订文件,在这个资源库中。所以我没有任何东西可以作比较。

于是我采取不同的措施,猜测着冲突是由限制单个字节引起的,我写了交换每个字节的程序,是这解压缩得到结果。因为这个类文件压缩过后仅有10K,花了很多时间解压出之后的结果是2.5M。

这是我用的程序:

编译和运行的结果:

有一些错误出现(如果你在zlib的信息头中得到”no data”信息,zlib认为它运行的很好:))。但是我中途得到了下面的信息:

等到运行完结束,末尾获得了更多的记录(整理crc文件匹配了我们损坏的文件)。有一个很好的机会,在中间的记录,就是源代码的问题

在一个十六进制编辑器中对字节稍微做了一些调整,zlib解压缩(毫无错误!),然后管道输出”git hash-object”,报告了损坏文件的shal值,成功了!

我修正packfile文件本身:

发现’\xc7’来自与替换我们的“munge”程序。把原来的对象偏移(51653873)导出了偏移量51659518 。通过“munge”(5642)增加了代替部分的偏移量,然后增加了之前去掉的3字节的git信息头。

最后,”git fsck” 清理干净。

关于冲突本身来说,我很幸运它确实是一个字节。实际上,证明就是单独的位。0xc7字节发生冲突成为0xc5.所以推测由错误的硬件引起,或者物理射线。

紧接着,中止关注于解压缩的输出是错的吗?我本会一直看前面的部分这样永远不会发现它。下面是解压缩后冲突数据的不同,真正的数据文件:

调整了一个字节,最终仍然是有效的,可读的C碰巧做了完全不同的事情!一次不同尝试会造成幸运的日子,看看zlib的输出可能确实有用,正如大多数随机的改变也许就会破坏C代码。

但更重要的是,git的hash、检验和引起了在另外一个系统中,很容易不被检测问题。这个结果仍然会编译,但是可能就引起一个有趣的bug(归咎于一些随机性的提交)

收藏 评论

关于作者:伯乐在线读者

① 本账号用于发布那些在伯乐在线无账号的读者的投稿,包括译文和原创文章。② 欢迎加入伯乐在线专栏作者:http://blog.jobbole.com/99322/ 个人主页 · 我的文章 · 32

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部