2009-06-10 7 views
16

He escuchado discusiones sobre cómo los archivos de OpenOffice (ODF) se comprimen en archivos zip de XML y otros datos. Así que hacer un pequeño cambio en el archivo puede potencialmente cambiar totalmente los datos, por lo que la compresión delta no funciona bien en los sistemas de control de versiones.Descomprime archivos de OpenOffice para un mejor almacenamiento en el control de versión

He hecho pruebas básicas en un archivo de OpenOffice, descomprimiéndolo y luego volviéndolo a comprimir sin compresión. Utilicé la utilidad de compresión de Linux para mi prueba. OpenOffice lo abrirá felizmente.

Así que me pregunto si vale la pena desarrollar una pequeña utilidad para ejecutar en archivos ODF cada vez justo antes de comprometerme con el control de versiones. ¿Alguna idea sobre esta idea? Posibles mejores alternativas?

En segundo lugar, ¿cuál sería una buena y sólida manera de implementar esta pequeña utilidad? Bash shell que llama zip (probablemente solo Linux)? ¿Pitón? ¿Algún problema que se te ocurra? Obviamente, no quiero manipular accidentalmente un archivo, y hay varias maneras en que podría suceder.

trampas posibles que se me ocurren:

  • espacio en disco insuficiente
  • algún otro problema de permisos que impide la escritura en el archivo o archivos temporales
  • documento ODF está encriptada (probablemente sólo debe salir de estos solos; el cifrado probablemente también provoque grandes cambios de archivos y, por lo tanto, impida la compresión delta eficiente)

Respuesta

6

Puede considerar almacenar documentos en formato FODT - formato XML plano.
Esta es una solución alternativa relativamente nueva disponible.

El documento se acaba de guardar descomprimido.

Más información está disponible en https://wiki.documentfoundation.org/Libreoffice_and_subversion.

+0

El uso del formato * .fodt y * .fods para los documentos es la manera más fácil de mantener los archivos de libreoffice calc y writer en control de versiones. No hay necesidad de utilidades o ganchos de confirmación de lujo y los beneficios del control de versión de texto sin formato están todos allí. – FvD

14

Primero, el sistema de control de versiones que desee utilizar debería d ganchos de soporte que se invocan para transformar el archivo de la versión en el repositorio al que está en el área de trabajo, como por ejemplo filtros de limpieza/borrado en Git de gitattributes.

En segundo lugar, se puede encontrar tal filtro, en lugar de escribir uno mismo, por ejemplo rezip de "Management of opendocument (openoffice.org) files in git" hilo en la lista de correo de git (pero véase la advertencia en "Followup: management of OO files - warning about "rezip" approach"),

Usted puede también navegar responde en el hilo "Tracking OpenOffice files/other compressed files with Git" o intenta encontrar la respuesta dentro del hilo "[PATCH 2/2] Add keyword unexpansion support to convert.c".

Esperamos que ayuda a

+0

Excelente información. Estoy más interesado en Subversion y Mercurial en este momento. No creo que Subversion tenga la función de tipo limpieza/borrado. No tengo idea de Mercurial: soy relativamente nuevo en eso. –

+0

@Craig: Mercurial tiene ganchos. – Borealid

1

Aquí es un script en Python que he juntado. Hasta el momento se han realizado pruebas mínimas. Hice pruebas básicas en Python 2.6. Pero prefiero la idea de Python en general porque debe abortar con una excepción si se produce algún error, mientras que un script bash puede no hacerlo.

Esto primero comprueba que el archivo de entrada sea válido y no esté descomprimido. Luego copia el archivo de entrada en un archivo de "copia de seguridad" con la extensión ".bak". Luego descomprime el archivo original, sobrescribiéndolo.

Estoy seguro de que hay cosas que he pasado por alto. Por favor, siéntase libre de dar su opinión.


#!/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() 

Esto es en un Mercurial repository in BitBucket.

3

He modificado el programa python en Craig McQueen's answer solo un poco.Los cambios incluyen:

  • comprobar realidad el regreso de testZip (de acuerdo con los documentos, parece que el programa original estará feliz de proceder con un archivo zip corrupto más allá de la etapa checkzip).

  • Vuelva a escribir el for-loop para comprobar que los archivos ya descomprimidos sean una sola instrucción if.

Aquí es el nuevo programa:

#!/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

Aquí hay otro programa me encontré con: store_zippies_uncompressed por Mirko Friedenhagen.

El wiki también muestra cómo integrarlo con Mercurial.

0

Si no necesita el ahorro de almacenamiento, pero solo desea poder diferir los archivos de OpenOffice.org almacenados en su sistema de control de versiones, puede usar las instrucciones en el oodiff page, que le indica cómo hacer que Oodiff sea el predeterminado diff para formatos OpenDocument bajo git y mercurial. (También se menciona SVN, pero ha pasado tanto tiempo desde que utiliza SVN regularmente no estoy seguro de si esas son las instrucciones o limitaciones.)

(I encontraron esta usando Mirko Friedenhagen's page (citado por Craig McQueen arriba))

Cuestiones relacionadas