Si tienes un repositorio git, y luego de haber realizado varios commits necesitas crear un paquete con todos los archivos modificados manteniendo la estructura de carpetas ¿cómo se podría hacer un comando en un sistema linux?
Hacerlo con línea de comandos es posible y muy sencillo, y todo se resume en el siguiente comando:
cp --parents `git diff --name-only <HASH INICIAL> <HASH FINAL>` <carpeta destino>
También podrías escribir:
cp --parents `git diff --name-only <HASH INICIAL> HEAD` <carpeta destino>
Donde:
- <HASH INICIAL> es el que corresponde al commit a partir del cual queremos obtener los cambios.
- <HASH FINAL> es el que corresponde al commit hasta donde queremos obtener los cambios
- <carpeta destino> es donde queremos copiar los archivos modificados.
- HEAD, para este caso lo escribimos textualmente y se refiere al HEAD de nuestro repositorio. Usualmente apunta al último commit de la rama en la que nos encontramos. Si no estás seguro a que commit apunta HEAD en tú repositorio puedes ejecutar el comando: git show HEAD.
Revisemos paso a paso. Primero veamos como listar los archivos modificados con git:
git diff --name-only <HASH INICIAL> HEAD
git diff --name-only <HASH INICIAL> <HASH FINAL>
Este es un ejemplo
ricardo@ricardo ~/prueba (master) $ git diff --name-only 44e48d1c0853223a0653cb HEAD
bebidas/cerveza.txt
bebidas/vino.txt
comidas/tacos.txt
ricardo@ricardo ~/prueba (master) $
Los archivos bebidas/cerveza.txt, bebidas/vino.txt y comidas/tacos.txt son los que no existían en el commit 44e48d1c... y si están presentes en el HEAD. El comando diff de git nos muestra la diferencia entre dos commits. Si adicionalmente enviamos el parámetro "name-only" solo nos mostrará los nombres de los archivos modificados, como en el ejemplo anterior.
Ahora, considerando que podemos usar el commando cp para copiar archivos, podríamos hacer lo siguiente:
cp `git diff --name-only cbb80b49aea4368e43fe7d966d1404a92fbf539b HEAD` <carpeta destino>
Sin embargo, no nos mantendrá la estructura original. Para lograrlo, podemos hacer uso del parámetro "parents" de cp.
Nuestro comando quedaría de la siguiente manera:
cp --parents `git diff --name-only <HASH INICIAL> HEAD` /home/ricardo/destino
O si es entre dos commits conocidos:
cp --parents `git diff --name-only <HASH INICIAL> <HASH FINAL>` <carpeta destino>
Utilizando el ejemplo anterior para enviar los archivos a /home/ricardo/destino el comando sería:
cp --parents `git diff --name-only 44e48d1c0853223a0653cb HEAD` /home/ricardo/destino
Con el siguiente resultado:
Hay que tener en cuenta que si se han borrado archivos este comando no funcionará del todo bien. A lo que teníamos en el ejemplo anterior se agregó un nuevo commit, donde se borra vino.txt. El hash a922a1f69ed... es del commit anterior a nuestra acción de borrar el archivo. Si se ejecuta el comando:
cp --parents `git diff --name-only a922a1f69ed4b7de28d HEAD` /home/ricardo/destino
Y produce la siguiente salida:
cp: cannot stat 'bebidas/vino.txt': No such file or directory
Lo cual tiene lógica porque ya no encuentra el archivo borrado.
Me pareció interesante el artículo
Comentario
Interesante tema. ¿Podrían…
Interesante tema. ¿Podrían profundizar más en el uso de git o crear videotutoriales?
excelente
lo que buscaba saludos
Añadir nuevo comentario