Раскройте файлы 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. Я не уверен, что это инструкции или ограничения.)

(я нашел это, используя страницу Мирко Фриденхагена (процитировано Крейгом МакКуином выше))