SVN克隆或更新遇到Error: Checksum mismatch for xxx

文章目录

前言

TortoiseSVN 作为版本控制常用的工具,有一个更为人们熟知的名字 SVN,客观的讲SVN的门槛相比Git而言还是低一些的,用来存储一些文件并保留历史记录比较方便,但使用SVN还是会经常需要这样那样的问题,特别是当仓库很大的时候,提示的问题往往让初学者、甚至是经常使用的人一脸懵,比如这个 Checksum mismatch for 问题,通常SVN问题都有一个终极解法,那就是重新克隆一份再操作,这就像大多数的电脑问题重启后就能解决一样,不过偶尔有一些情景不适合采用重新克隆的解法,我们就得想一个更精确的办法去解决了。

问题的产生

在克隆一个300多G的库时,报了下面这个错误,总结来说这个错误表述的就是"心有所求而不得",期望得到一个md5是 2c448c9f40b0dd561539b80ec3cfcaa2bundle_103_cp_delafere_e_buff_wuqi.ab文件,但是下载后的文件计算md5得到的是 a2e41ec2779a23d88b31e4237ad43ceb,并不是自己想要的,提示如下:

bash 复制代码
Error: Checksum mismatch for
Error:  'E:\gameproject\prefabs\bundle_103_cp_delafere_e_buff_wuqi.ab':
Error:
Error:    expected:  2c448c9f40b0dd561539b80ec3cfcaa2
Error:      actual:  a2e41ec2779a23d88b31e4237ad43ceb

探索解决方案

先说说网上一些常见的解决办法:

  1. 删除了整个库,重新克隆下载,这个方法99%可行,但是整个库太大了,我不想重新下载
  2. Clean up 之后继续更新,我试过了不行
  3. 先在出错的文件夹下执行 svn update --set-depth empty 删除文件夹下所有文件,再执行 svn update --set-depth infinity 更新,这是流传的最广的解决办法,在我这不行
  4. 先在 Update to revision... 中选择 Update Depth 为 Only this item 更新,然后再选择 Fully recursive 更新,原理上和上一步类似,在我这也不行

其实仔细分析这几种解决方案的本质,都是把错误的文件删除掉再重新更新,但是为什么不起作用呢?

从我最终解决问题的方法来看是,针对我遇到的问题,上面提到的一些方法并没有将错误的文件成功删除,简单分析下svn克隆和更新的过程,很可能不准确,但是我不在此处不深究,暂时还用不到这一块。

我们在传输文件时为了保证文件的完整性,经常会用一些摘要算法比如md5、sha1等来计算文件摘要,通过比较文件摘要来判断文件传输是否完整,而SVN这个工具每时每刻都在上传下载传输文件,所以也用到了摘要比对的技术。

以较新的SVN版本为例,是将sha1和md5存到了.svn/wc.db中(太老的版本md5是存储到文件中的),下载时先更新 wc.db,然后将原始文件的元文件下载到 .svn/pristine 文件夹中,然后比较这些文件的md5值与 wc.db 记录的md5值是否一致,如果一样就从元文件中提取出真正的文件放到库中,这个文件就算下载完了,如果不一致就会报出上面的错误。

分析过后我们只要找到错误的元文件,删除后重新下载就解决了。

正式的解决方法

首先打开从 .svn/wc.db 中查找的元文件的名字,可以使用你熟悉的工具,我用的是 SQLiteSpy.exe有图形界面方便一下,最基础的也可以用 sqlite3.exe 这种命令行的工具,执行以下sql语句:

sql 复制代码
select * from NODES where local_relpath = 'prefabs/bundle_103_cp_delafere_e_buff_wuqi.ab'

执行过后可以查到checksum列的值为 $sha1$f9fd60e244a004cc30fcc83e8e59e7466b3dca6a,这就是元文件的名字,也可以通过下面的语句查到md5值

sql 复制代码
select * from PRISTINE where checksum = '$sha1$f9fd60e244a004cc30fcc83e8e59e7466b3dca6a';

结果中md5_checksum列的值为 $md5$2c448c9f40b0dd561539b80ec3cfcaa2 就是报错中提到的那个期望值了。

接下来进入 .svn/pristine/f9 文件夹,删除 f9fd60e244a004cc30fcc83e8e59e7466b3dca6a.svn-base 文件,然后在仓库根目录更新就正常了

背后的故事

问题解决了,那么产生的这种问题的原因是什么呢?为什么会md5值不一致呢?我们知道文件的md5值是根据文件内容计算出来的,下载后的文件md5不是预期的值说明文件内容发生了变化。

我用比较工具对比了正常的文件和出错的文件发现,两个大小都为29949字节的文件,其中有一个字节发生了偏差,正确的文件该字节值为 2F,而错误的文件对应值为 2E,就弄错了这一个字节,导致SVN的文件比对报错了。

这一个字节差异产生的原因,可能有很多种,比如传输过程中数据损坏、压缩或加密问题、数据损坏或硬盘问题,我这里大概率是因为下载时机器重启的原因。

这让我想起了7、8年前下载游戏服务器包无法启动的问题,当时下载完启动各种异常,比较文件大小也是一样的,但是计算md5后发现不同,应该也是传输过程中发生了错误。

总结

  • SVN遇到的问题有90%都可以通过完整删除后重新克隆下载的方式解决
  • 老版本的文件checksum值存储到 .svn/entries 文件中,较新版本的文件将这些值存储在 .svn/wc.db
  • 通过 select * from NODES where local_relpath = 'xxx' 方式可以从 .svn/wc.db 中查到文件的 sha1值
  • svn/pristine 中找到 $sha1$.svn-base 删除即可重新下载了

==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==


待到秋来九月八,我花开后百花杀。有些句子在经历了一些事以后,自然而然就有了新的理解,这与儿时死记硬背下来的赏析是完全不同的~

相关推荐
Bonne journée11 小时前
SQLite数据库是什么?DB Browser for SQLite是什么?
数据库·sqlite
q567315231 天前
使用 Python 编辑 XML 文件中的文本字段
xml·java·数据库·python·sqlite
Mephisto.java2 天前
【大数据学习 | kafka】kafka的偏移量管理
大数据·sql·oracle·sqlite·json·hbase
doll ~CJ2 天前
SQLite的BLOB数据类型与C++二进制存储学习记录
c++·sqlite·blob·图像数据存取·bitset标准库
啧不应该啊3 天前
Django数据模型on_delete属性值
数据库·django·sqlite
荣世蓥4 天前
数据库_SQLite3
数据库·sqlite
Cachel wood4 天前
Django3 + Vue.js 前后端分离书籍添加项目Web开发实战
开发语言·前端·vue.js·python·数据分析·sqlite·pandas
OP_YH4 天前
【IDEA配置】IDEA 配置Java web项目(采用Tomcat容器)
java·后端·svn·tomcat·intellij-idea
小菜鸟学代码··4 天前
sqlite数据库
jvm·数据库·sqlite
DN金猿4 天前
Electron+Vue3+TS+sqlite3项目搭建加入sqlite3后无法运行问题
javascript·vue.js·sqlite·node.js·ecmascript