为什么Subversion无法标记已修改的Microsoft Excel电子表格文件?

7
我遇到了一些我没想到的Subversion行为,并几乎是偶然发现的:修改的文件没有被标记为修改。
我的一个单元测试涉及一个Microsoft Excel电子表格作为输入文件。该单元测试计算CRC校验和;由于校验和改变,我的测试开始失败。
测试文件存储在SVN中,并具有MIME类型“application/octet-stream”,因此被SVN视为二进制文件。
我从TortoiseSVN和SVN命令行客户端获得了相同的行为,在这种情况下,两者都基于SVN 1.6:当文件在Excel中打开时,它被打开的事实必须编码在文件本身中; SVN显示文件已修改。但是,当文件再次关闭(不保存)时,它似乎返回到其未修改的状态:也就是说,svn status不列出Excel文件;由于数据是二进制的,svn diff不产生任何输出。
问题是该文件现在与存储在存储库中的文件不进行二进制比较。(如果导出新的副本,则无法将其与打开并关闭的副本进行二进制比较。)从用户的角度来看,该文件显然没有更改,因此在语义上,SVN的响应是合理的。但在语法上却不是这样;而SVN本质上是语法的。
我找不到原因的部分是为什么SVN没有将文件标记为已修改。我无法想象SVN对Excel文件有任何特殊处理(在任何情况下,MIME类型不是与MS Excel相关联的特定类型);未定义SNV关键字属性。同样,我可以想象Excel不知道隐藏的.svn子目录中存储的SVN工作副本信息的内容。
你有什么线索吗?谢谢,Rob。
3个回答

4
Subversion假定“最后修改”时间戳不是错误的。如果时间戳未更改,文件内容不会被检查更改。我认为所有版本控制系统都是这样做的,否则检查本地修改将变得难以忍受。
编辑:关于SVN在这方面的工作原理的详细信息,请参阅源代码中SVN工作副本库的questions.c

1
正是我打算建议的 - 检查时间戳 :-) 我曾经遇到过一些奇怪的问题,其中它没有被正确设置,这与这个问题非常相似。 - Michael Berry
再次感谢您的好建议。我以为我已经看到了时间戳的更新。我想知道Excel是否在打开时更改时间戳,但在关闭而不保存时将其更改回来。稍后我会再次检查(更仔细地)。 - Rhubbarb
我刚遇到了这个问题,hashcheck 显示的校验和与 TortoiseSVN 不一致。查看了 SVN 校验和值,它仍然保持不变。你知道有没有任何客户端能够发出类似于“无论时间戳如何,始终对 *.xls 文件进行校验和”的指令吗? - SiegeX
1
@SiegeX:不,但是你可以通过手动更改时间戳来强制SVN进行完整比较。编写一个脚本,在给定目录中的每个xls文件上调整时间戳应该不难。 - Wim Coenen

3

Excel在打开文件时总是会锁定文件,并将时间戳设置为当前日期。当你不保存而关闭文件时,Excel会将时间戳还原回去。这会导致SVN忽略该文件。

至于更改的内容,我不确定。你能重现这个问题吗?


谢谢。是的,问题可以重现。这听起来像是一个可能的解释;我在对Wim的回复中已经几乎说过了这一点,但独立观察到这一点很好。明天我会在工作中检查这个问题。 - Rhubbarb
只是确认一下:这正是发生的事情。当打开Excel文件时,文件内容会被更改(例如可以通过md5sum看到),并且修改时间也会更改。如果在不保存的情况下关闭文件,则文件内容不会更改,但也不会恢复到原始状态;而修改时间会恢复到打开之前的值。 - Rhubbarb
3
刚刚发现这个链接:http://spreadsheetpage.com/index.php/oddity/who_last_opened_that_file/,看起来Excel会保存文件最后打开者的姓名(可能还有其他信息),即使你没有保存该文件。很奇怪。 - Martin
@Marin,发现得真好,这肯定是问题所在。我看到解决这个问题的唯一方法是:1)告诉Excel停止在幕后修改文件;2)更改它进行修改时的时间戳;3)让SVN客户端强制重新计算*.xls文件的校验和,而不考虑时间戳值。不幸的是,我不知道如何做这些事情,你知道吗? - SiegeX

1

Excel打开文件时是否可能将其锁定,SVN无法访问该文件以查看其是否已更改?


我认为微软的应用程序通常会在一个单独的隐藏文件中指示锁定情况(类似于 ~file.doc),但是我认为 Excel 不同。锁定是一个线索,但我不认为这就是全部,我也不认为访问被阻止了。(我需要更多实验。) - Rhubbarb

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