16

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

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

所以我想知道是否值得在我提交版本控制之前开发一个小实用程序来在 ODF 文件上运行。对这个想法有什么想法吗?可能的更好的选择?

其次,实现这个小实用程序的好方法是什么?调用 zip 的 Bash shell(可能仅限 Linux)?Python?你能想到什么陷阱吗?显然我不想意外损坏文件,并且有几种可能发生的方式。

我能想到的可能的陷阱:

  • 磁盘空间不足
  • 其他一些阻止写入文件或临时文件的权限问题
  • ODF 文档已加密(可能应该只保留这些;加密可能还会导致大文件更改,从而阻止有效的增量压缩)
4

6 回答 6

14

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

其次,您可以找到这样的过滤器,而不是自己编写一个,例如从git 邮件列表上的“ Management of opendocument (openoffice.org) files in git ”线程重新压缩(但请参阅“后续:OO 文件管理 - 警告”中的警告关于“重新压缩”方法“),

您也可以在“使用 Git 跟踪 OpenOffice 文件/其他压缩文件”线程中浏览答案,或尝试在“ [PATCH 2/2] Add keyword unexpansion support to convert.c ”线程中找到答案。

希望有帮助

于 2009-06-10T14:23:49.173 回答
6

您可以考虑以 FODT 格式存储文档 - 平面 XML 格式。
这是可用的相对较新的替代解决方案。

文档只是解压缩后存储。

更多信息可在https://wiki.documentfoundation.org/Libreoffice_and_subversion获得。

于 2015-03-10T04:19:13.290 回答
3

我稍微修改了Craig McQueen 的回答中的 python 程序。变化包括:

  • 实际上检查 testZip 的返回(根据文档,看起来原始程序很乐意在 checkzip 步骤之后继续处理损坏的 zip 文件)。

  • 重写 for 循环以检查已经解压缩的文件是否为单个 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()
于 2010-03-06T19:47:22.483 回答
2

这是我偶然发现的另一个程序: Mirko Friedenhagen 的store_zippies_uncompressed

wiki还展示了如何将其与 Mercurial 集成。

于 2010-03-16T07:43:24.393 回答
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()

这是在 BitBucket 的 Mercurial 存储库中

于 2009-06-13T14:08:42.743 回答
0

如果您不需要节省存储空间,而只是希望能够比较存储在您的版本控制系统中的 OpenOffice.org 文件,您可以使用oodiff 页面上的说明,该页面说明如何使 oodiff 成为 OpenDocument 的默认差异git 和 mercurial 下的格式。(它还提到了 SVN,但是自从我经常使用 SVN 已经很久了,我不确定这些是说明还是限制。)

(我使用Mirko Friedenhagen 的页面找到了这个(上面由 Craig McQueen 引用))

于 2012-07-15T01:22:12.277 回答