Раскройте файлы OpenOffice для лучшего хранения в управлении версиями
Я слышал дискуссию о том, как файлы OpenOffice (ODF) представляют собой сжатые zip файлы XML и других данных. Поэтому внесение незначительных изменений в файл может потенциально полностью изменить данные, поэтому дельта-сжатие не работает в системах контроля версий.
Я провел базовое тестирование в файле OpenOffice, разархивировав его, а затем переставив его с нулевым сжатием. Я использовал утилиту zip Linux для тестирования. OpenOffice все равно с радостью откроет его.
Так что мне интересно, стоит ли разрабатывать небольшую утилиту для работы в файлах ODF каждый раз перед тем, как я начну использовать контроль версий. Любые мысли об этой идее? Возможные альтернативы?
Во-вторых, что было бы хорошим и надежным способом реализовать эту небольшую полезность? Bash оболочка, которая вызывает zip (возможно, только Linux)? Python? Вы можете думать о каких-либо проблемах? Очевидно, я не хочу случайно искажать файл, и есть несколько способов, которые могут произойти.
Возможные ошибки, о которых я могу думать:
- Недостаточно места на диске
- Некоторые другие проблемы с разрешениями, которые предотвращают запись файла или временных файлов
- Документ ODF зашифрован (возможно, он должен просто оставить его в покое, что, вероятно, также приводит к большим изменениям файла и, таким образом, предотвращает эффективное дельта-сжатие)
Ответы
Ответ 1
Вот Python script, который я собрал вместе. До сих пор у него было минимальное тестирование. Я провел базовое тестирование в Python 2.6. Но я предпочитаю идею Python вообще, потому что он должен прерываться с исключением, если возникает какая-либо ошибка, тогда как bash script может не быть.
Вначале проверяется, что входной файл действителен и еще не сжат. Затем он копирует входной файл в "резервный" файл с расширением ".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 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 data to output, making sure it 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 в BitBucket.
Ответ 2
Во-первых, система управления версиями, которую вы хотите использовать, должна поддерживать перехваты, которые вызывают, чтобы преобразовать файл из версии в репозиторий в рабочую область, например, фильтры очистки/размытия в Git от gitattributes.
Во-вторых, вы можете найти такой фильтр, вместо того, чтобы писать его самостоятельно, например rezip из Управление opendocument (openoffice. org) в разделе git "в списке рассылки Git (но см. предупреждение в разделе Followup: управление OO файлами - предупреждение о" rezip "),
You can also browse answers in "Tracking OpenOffice files/other compressed files with Git" thread, or try to find the answer inside "[PATCH 2/2] Add keyword unexpansion support to convert.c" thread.
Надеюсь, что это поможет
Ответ 3
Вы можете рассмотреть возможность хранения документов в формате FODT - плоский формат XML.
Это относительно новое альтернативное решение.
Документ просто распаковывается.
Дополнительная информация доступна по адресу https://wiki.documentfoundation.org/Libreoffice_and_subversion.
Ответ 4
Я немного изменил программу python в Craig McQueen. Изменения включают:
-
Фактически проверяя возврат 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 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 data to output, making sure it uncompressed
for fileObject in inputZipFile.infolist():
fileData = inputZipFile.read(fileObject)
outFileObject = fileObject
outFileObject.compress_type = zipfile.ZIP_STORED
outputZipFile.writestr(outFileObject, fileData)
outputZipFile.close()
Ответ 5
Здесь другая программа, на которую я наткнулся: store_zippies_uncompressed от Mirko Friedenhagen.
wiki также показывает, как интегрировать его с Mercurial.
Ответ 6
Если вам не нужна экономия на хранении, но вы просто хотите, чтобы у вас были файлы OpenOffice.org, хранящиеся в вашей системе управления версиями, вы можете использовать инструкции на страница oodiff, в которой рассказывается, как сделать oodiff стандартным diff для форматов OpenDocument под git и mercurial. (Он также упоминает SVN, но это было так давно, что я регулярно использовал SVN. Я не уверен, что это инструкции или ограничения.)
(я нашел это, используя страницу Мирко Фриденхагена (процитировано Крейгом МакКуином выше))