2011-04-09 15 views
105

sólo quiero obtener una lista de los archivos modificados entre dos revisiones, que es simple:Git diff --name sólo y copiar esa lista

git diff -–name-only commit1 commit2 > /path/to/my/file 

Pero, ¿qué debo escribir, si quiero copiar todos los archivos enumerados a otro lugar? Y necesito una estructura de directorios completamente idéntica para los archivos copiados.

Por ejemplo, he modificados y agregados archivos:

/protected/texts/file1.txt 
/protected/scripts/index.php 
/public/pics/pic1.png 

quiero tener en /home/changes/ todas esas modificaciones y añadidos archivos:

/home/changes/protected/texts/file1.txt 
/home/changes/protected/scripts/index.php 
/home/changes/public/pics/pic1.png 
+0

No acabo de entender lo que está tratando de lograr ... que se propagan a cambios diferentes clones? creando parches? ¿parchear archivos fuera de un repositorio git? – knittl

+0

No parche, pero estructura de copia exacta de los archivos modificados. Como parche, pero con archivos sólidos – BazZy

+0

Y sí, parcheando archivos fuera del repositorio de git - objetivo más cercano para mí :) – BazZy

Respuesta

86

Prueba el siguiente comando, que he probado:

$ cp -pv --parents `git diff --name-only` DESTINATION-DIRECTORY 
+1

Gracias por la pista '' cp --parents'', ¡he deseado esa opción durante años y nunca supe que existía! ..obviously nunca me molesté en buscarlo tampoco = \ –

+1

Tenga en cuenta que esto no funciona en Mac, ya que la opción '--parents' de' cp' no está disponible. –

+0

¿Algún consejo sobre usar esto si los archivos tienen caracteres inusuales? Espacio en blanco, personajes nórdicos. –

9

La siguiente debería funcionar bien:

git diff -z --name-only commit1 commit2 | xargs -0 -IREPLACE rsync -aR REPLACE /home/changes/protected/ 

Para explicar más:

  • El -z a git diff --name-only con los medios para generar la lista de archivos separados NUL bytes en lugar de saltos de línea, por si acaso los nombres de archivo tienen caracteres inusuales en ellos.

  • El -0 a xargs dice que se interpreta la entrada estándar como una lista de parámetros separados por NUL.

  • Se necesita -IREPLACE ya que de manera predeterminada xargs anexaría los parámetros al final del comando rsync. En cambio, eso dice ponerlos donde está el REPLACE más tarde. (Eso es un buen consejo de this Server Fault answer.)

  • El parámetro -a-rsync medio para preservar permisos, la propiedad, etc., si es posible. El -R significa utilizar la ruta relativa completa al crear los archivos en el destino.

Actualización: si tiene una versión antigua de xargs, tendrá que utilizar la opción -i en lugar de -I. (El primero está en desuso en versiones posteriores de findutils.)

+0

Tengo un error : xargs: opción no válida - I – BazZy

+0

Eso es extraño, ¿qué sistema operativo estás usando? Si se trata de una distribución de Linux, ¿cuál y qué dice 'xargs --version'? –

+0

GNU xargs versión 4.1 – BazZy

5

Aquí hay una sola línea:

lista de archivos cambiados & paquete de ellos como * .zip:

Lista
git diff --name-only | zip patched.zip [email protected] 

última comprometidos archivos modificados & empacar como archivos *.postal:

git diff --name-only HEAD~ HEAD | zip patched.zip [email protected] 
+0

Si está utilizando Windows, puede descargar la línea de comando zip desde https://sourceforge.net/projects/gnuwin32/files/zip/ – Radon8472

3
zip update.zip $(git diff --name-only commit commit) 
1

Funciona perfectamente.

git diff 1526043 82a4f7d --name-only | xargs zip update.zip 

git diff 1526043 82a4f7d --name-only |xargs -n 10 zip update.zip 
0

Nadie ha mencionado cpio que es fácil de escribir, crea enlaces duros y se ocupa de los espacios en los nombres de archivo:

git diff --name-only $from..$to | cpio -pld outdir