2009-06-10 63 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(克雷格·麥昆以上)引用)