2011-09-21 11 views
6

Hay muchas soluciones para crear un parche de nivel de archivo para archivos de texto y similares. Lo que estoy buscando es un comando sencillo script/shell que compare oldversion/newversion/y me proporcione un árbol de archivos que necesito copiar sobre oldversion para que sea igual a newversion (suponiendo que los archivos no se eliminen en la actualización) versión). Tenga en cuenta que las dos carpetas contienen archivos binarios y de texto.Diferencia de dos árboles de directorios para crear un parche de nivel de archivo/carpeta (incluidos los archivos binarios)

Anteriormente, estábamos usando el hack:

fdupes -qrf newversion/ oldversion/ | grep "newversion" | xargs rm;

que nos deja con la carpeta "newversion" que podrían ser empaquetado como un parche.

Lamentablemente, esto resultó ser desastroso porque fdupes no tiene en cuenta los nombres de archivo.

Lo que sería fantástico es algo así como fdupes que realmente incluía el nombre de archivo en la comparación.

+0

¿Está buscando solo la lista de archivos "nuevos" y no archivos "modificados" en newversion /? –

+0

Ambos archivos nuevos y archivos modificados. –

Respuesta

5

El comando diff se puede pedir a los nombres de archivo de salida que se diferencian.

diff --quiet --recurse --unidirectional-new-file OLDDIR NEWDIR 

Files old/main and new/main differ 
Files old/main.cpp and new/main.cpp differ 
Files old/Makefile and new/Makefile differ 
Files old/sounds/popalien.wav and new/sounds/popalien.wav differ 
Files old/sounds/saucer.wav and new/sounds/saucer.wav differ 

Por supuesto, no es una salida agradable, pero ya que usted está buscando solamente los archivos nuevos para empaquetar como un parche, un tubo de sed rápida funciona de maravilla:

diff --quiet --recurse -unidirectional-new-file OLDDIR NEWDIR | \ 
    sed "s/^.* and \(.*\) differ/\1/" 

(rotos para facilitar la lectura)

new/main 
new/main.cpp 
new/Makefile 
new/sounds/popalien.wav 
new/sounds/saucer.wav 

espacios alrededor 'y' y que precede 'difieren'

el orden de los operandos diferenciar hace una diferencia, el primer argumento queda de 'y', el segundo es después. Ten cuidado con eso.

Además, si elimina un archivo de NEWDIR, no lo encontrará como proporcionado, solo se agregarán o cambiarán los archivos. Para generar también nombres de archivo para archivos que no se encuentran en ninguno de los subdirectorios, reemplace el --unidirection-new-file con --new-file. (existen opciones cortas para todos excepto --unidireccional ..)

1

diff -ruN oldversion newversion

0

Sé que ha sido mucho tiempo. Necesitaba la misma solución. Encontré esta publicación pero no fue suficiente. Entonces encontré que rsync puede hacer el trabajo IFF que `` parche`` copias idénticas, y no necesita fusionarse con otros cambios. Tengo la intención de usar esto con la actualización de espejos yum en máquinas desconectadas. Mi solución completa es un poco más complicado, y le escribo comandos de la memoria por lo que algunos detalles finos podrían estar equivocado, pero en el fondo:

# create identical copy "copy.0" 
rsync -a master/ copy.0/ 

# Presumably transfer copy.0/ to another machine for offline use 
# but copy.0 must not mutate outside of this process or sync probably 
# will not work. 

# some time later update master, e.g. rsync master from upstream mirror 
# mutates master in some way, changes/adds/removes remove files including 
# binaries 
echo -n $'\001\002' > master/new.bin 
rm master/gone.bin 

# generate rsync batch that can be used to ``patch`` copy.0 
# to become identical to master 
rsync -a --delete --itemize-changes --only-write-batch=copy.0.batch \ 
    master/ copy.0/ 
# now the file copy.0.batch contains only the deltas to be applied 

# transfer the batch file to where it needs to be applied 

# apply the batch to copy.0 
rsync -a --delete --itemize-changes --read-batch=copy.0.batch copy.0/ 

Este se encarga de supresiones y muchas otras cosas, probablemente permisos , timestamps, etc., pero creo que podría no manejar enlaces duros como enlaces duros y probablemente los creará como archivos separados no vinculados.

Cuestiones relacionadas