2009-06-10 34 views
16

我听说过有关OpenOffice(ODF)文件是如何压缩XML和其他数据的zip文件的讨论。因此,对文件进行微小更改可能会完全改变数据,因此增量压缩在版本控制系统中效果不佳。解压缩OpenOffice文件以更好地存储版本控制

我已经对OpenOffice文件进行了基本测试,将其解压缩,然后用零压缩进行重新压缩。我使用Linux zip实用程序进行测试。 OpenOffice仍然乐意打开它。

所以我想知道是否值得开发一个小实用程序,每次在我承诺版本控制之前在ODF文件上运行。对这个想法有什么想法?可能更好的选择?其次,如何实现这个小实用程序,这将是一种很好而健壮的方法?调用zip的Bash shell(可能只有Linux)?蟒蛇?任何你能想到的陷阱?很明显,我不想意外地损坏一个文件,并且有几种方法可能发生。

可能的陷阱,我能想到的:

  • 磁盘空间不足
  • 其他一些权限问题,防止写入文件或临时文件
  • ODF文档被加密(可能应见好就收这些孤单;加密可能还会导致大文件更改,从而阻止有效的增量压缩)

回答

14

首先,您要使用的版本控制系统d支持钩子,这些钩子可以将文件从存储库中的版本转换为工作区域中的文件,例如从gitattributes的Git中的clean/smudge过滤器。

其次,你可以找到这样的过滤器,而不是自己从“Management of opendocument (openoffice.org) files in git”混帐邮件列表上线(但请参阅“Followup: management of OO files - warning about "rezip" approach”的警告),

您也可以浏览写一个,例如重新压缩在“Tracking OpenOffice files/other compressed files with Git”线程中回答,或尝试在“[PATCH 2/2] Add keyword unexpansion support to convert.c”线程内找到答案。

希望帮助

+0

了不起的信息。目前我最感兴趣的是Subversion和Mercurial。我不认为Subversion有干净/污迹类型的功能。 Mercurial没有想法 - 我相对较新。 – 2009-06-10 16:16:28

+0

@克雷格:Mercurial有钩子。 – Borealid 2010-08-12 00:55:02

1

这里是我已经把一个Python脚本。到目前为止,它的测试已经很少了。我已经在Python 2.6中完成了基本的测试。但我更喜欢Python的概念,因为如果发生任何错误,它应该异常中止,而bash脚本可能不会。

这首先检查输入文件是否有效并且尚未解压缩。然后它将输入文件复制到“.bak”扩展名的“备份”文件中。然后它解压缩原始文件,覆盖它。

我确定有些事情我忽略了。请随时提供反馈。


#!/usr/bin/python 
# Note, written for Python 2.6 

import sys 
import shutil 
import zipfile 

# Get a single command-line argument containing filename 
commandlineFileName = sys.argv[1] 

backupFileName = commandlineFileName + ".bak" 
inFileName = backupFileName 
outFileName = commandlineFileName 
checkFilename = commandlineFileName 

# Check input file 
# First, check it is valid (not corrupted) 
checkZipFile = zipfile.ZipFile(checkFilename) 
checkZipFile.testzip() 

# Second, check that it's not already uncompressed 
isCompressed = False 
for fileObject in checkZipFile.infolist(): 
    if fileObject.compress_type != zipfile.ZIP_STORED: 
     isCompressed = True 
if isCompressed == False: 
    raise Exception("File is already uncompressed") 

checkZipFile.close() 

# Copy to "backup" file and use that as the input 
shutil.copy(commandlineFileName, backupFileName) 
inputZipFile = zipfile.ZipFile(inFileName) 

outputZipFile = zipfile.ZipFile(outFileName, "w", zipfile.ZIP_STORED) 

# Copy each input file's data to output, making sure it's uncompressed 
for fileObject in inputZipFile.infolist(): 
    fileData = inputZipFile.read(fileObject) 
    outFileObject = fileObject 
    outFileObject.compress_type = zipfile.ZIP_STORED 
    outputZipFile.writestr(outFileObject, fileData) 

outputZipFile.close() 

这是在Mercurial repository in BitBucket

3

我修改了Craig McQueen's answer中的python程序。变化包括:

  • 其实检查testZip的回报(根据文档,似乎原来的程序会很乐意与损坏的zip文件过去checkzip步骤进行)。

  • 重写for-loop以检查已经解压缩的文件是否是单个if语句。

下面是新程序:

#!/usr/bin/python 
# Note, written for Python 2.6 

import sys 
import shutil 
import zipfile 

# Get a single command-line argument containing filename 
commandlineFileName = sys.argv[1] 

backupFileName = commandlineFileName + ".bak" 
inFileName = backupFileName 
outFileName = commandlineFileName 
checkFilename = commandlineFileName 

# Check input file 
# First, check it is valid (not corrupted) 
checkZipFile = zipfile.ZipFile(checkFilename) 

if checkZipFile.testzip() is not None: 
    raise Exception("Zip file is corrupted") 

# Second, check that it's not already uncompressed 
if all(f.compress_type==zipfile.ZIP_STORED for f in checkZipFile.infolist()): 
    raise Exception("File is already uncompressed") 

checkZipFile.close() 

# Copy to "backup" file and use that as the input 
shutil.copy(commandlineFileName, backupFileName) 
inputZipFile = zipfile.ZipFile(inFileName) 

outputZipFile = zipfile.ZipFile(outFileName, "w", zipfile.ZIP_STORED) 

# Copy each input file's data to output, making sure it's uncompressed 
for fileObject in inputZipFile.infolist(): 
    fileData = inputZipFile.read(fileObject) 
    outFileObject = fileObject 
    outFileObject.compress_type = zipfile.ZIP_STORED 
    outputZipFile.writestr(outFileObject, fileData) 

outputZipFile.close() 
0

如果您不需要节省存储空间,但只是希望能够区分存储在版本控制系统中的OpenOffice.org文件,则可以使用oodiff page上的说明,该说明告诉您如何使oodiff成为默认值diff用于git和mercurial下的OpenDocument格式。 (它还提到SVN,但它已经这么长时间,因为我使用SVN经常我不知道如果这些都说明或限制。)

(我发现这个使用Mirko Friedenhagen's page(克雷格·麦昆以上)引用)