Распакуйте файлы OpenOffice для лучшего хранения в управлении версиями - PullRequest
16 голосов
/ 10 июня 2009

Я слышал обсуждение того, как файлы OpenOffice (ODF) представляют собой сжатые zip-файлы XML и других данных. Таким образом, внесение незначительных изменений в файл может потенциально полностью изменить данные, поэтому дельта-сжатие не работает в системах контроля версий.

Я провел базовое тестирование файла OpenOffice, разархивировал его, а затем разархивировал с нулевым сжатием. Для тестирования я использовал утилиту Linux zip. OpenOffice все равно с радостью откроет его.

Так что мне интересно, стоит ли разрабатывать небольшую утилиту для запуска ODF-файлов каждый раз перед тем, как перейти к управлению версиями. Есть мысли по поводу этой идеи? Возможные лучшие альтернативы?

Во-вторых, что было бы хорошим и надежным способом реализации этой маленькой утилиты? Оболочка Bash, которая вызывает zip (возможно, только для Linux)? Python? Есть какие-нибудь ошибки, о которых вы можете подумать? Очевидно, я не хочу случайно искажать файл, и это может произойти несколькими способами.

Возможные ошибки, о которых я могу думать:

  • Недостаточно места на диске
  • Некоторые другие проблемы с разрешениями, которые мешают записи файла или временных файлов
  • ODF-документ зашифрован (вероятно, следует просто оставить их в покое; шифрование, вероятно, также вызывает большие изменения файла и, следовательно, предотвращает эффективное дельта-сжатие)

Ответы [ 6 ]

14 голосов
/ 10 июня 2009

Во-первых, система управления версиями, которую вы хотите использовать, должна поддерживать хуки, которые вызываются для преобразования файла из версии в хранилище в рабочую область, как, например, фильтры clean / smudge в Git из gitattributes .

Во-вторых, вы можете найти такой фильтр вместо того, чтобы писать его самостоятельно, например rezip из " Управление файлами opendocument (openoffice.org) в потоке git " при рассылке git список (но см. предупреждение в " Followup: управление файлами OO - предупреждение о подходе" rezip ""),

Вы также можете просмотреть ответы в теме " Отслеживание файлов OpenOffice / других сжатых файлов с помощью Git " или попытаться найти ответ внутри " & # x5B; PATCH 2/2 & # x5D; Добавьте поддержку расширения ключевых слов в ветку convert.c".

Надеюсь, что поможет

6 голосов
/ 10 марта 2015

Можно рассмотреть возможность хранения документов в формате FODT - плоский формат XML.
Это относительно новое альтернативное решение.

Документ только что распакован.

Более подробная информация доступна на https://wiki.documentfoundation.org/Libreoffice_and_subversion.

3 голосов
/ 06 марта 2010

Я немного изменил программу на Python в Ответ Крейга МакКуина . Изменения включают в себя:

  • На самом деле проверка возврата testZip (в соответствии с документацией кажется, что исходная программа с радостью продолжит работу с поврежденным zip-файлом после шага checkzip).

  • Переписать цикл 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()
2 голосов
/ 16 марта 2010

Вот еще одна программа, с которой я столкнулся: store_zippies_uncompressed от Mirko Friedenhagen.

Вики также показывают, как интегрировать ее с Mercurial.

1 голос
/ 13 июня 2009

Вот скрипт 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 репозитории в BitBucket .

0 голосов
/ 15 июля 2012

Если вам не нужна экономия на хранении, но вы просто хотите иметь возможность просматривать файлы OpenOffice.org, хранящиеся в вашей системе управления версиями, вы можете воспользоваться инструкциями на странице oodiff , которая сообщает как сделать oodiff стандартным diff для форматов OpenDocument в git и mercurial. (В нем также упоминается SVN, но прошло уже много времени с тех пор, как я регулярно использовал SVN, и я не уверен, что это инструкции или ограничения.)

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

...