¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Git
  3. Consulta y operaciones del histórico
Extrait - Git Controle la gestión de sus versiones (conceptos, utilización y casos prácticos) (2a edicion)
Extractos del libro
Git Controle la gestión de sus versiones (conceptos, utilización y casos prácticos) (2a edicion) Volver a la página de compra del libro

Consulta y operaciones del histórico

Listar los commits con git log

Una de las características más importantes de un VCS es recuperar rápidamente un cierto número de datos; por ejemplo, las modificaciones realizadas desde una fecha concreta o los cambios en curso en el directorio de trabajo.

El comando git log nos permitirá ver mucha información sobre los commits. Este comando es muy potente y tiene muchas opciones. Basta consultar la ayuda de este comando para medir las posibilidades que ofrece.

Por defecto, git log muestra una lista de commits del repositorio en orden cronológico descendente. La salida puede ser muy importante (o incluso monstruosa según el tamaño del proyecto), ya que se muestran todos los commits realizados durante toda la vida del repositorio.

Para probar los comandos que permiten navegar en un repositorio fácilmente sin necesidad de crear un depósito y añadir mucho contenido, puede ser conveniente clonar un repositorio disponible en GitHub. El siguiente comando descarga el repositorio del framework web Django y lo coloca en la carpeta django:

git clone https://github.com/django/django.git 

Este comando se explicará con más detalle en el capítulo Compartir un repositorio, en la sección Clonar un repositorio remoto. Para hacerlo simple, este comando no solo descargará el código, sino todo el repositorio con todo el histórico y, por lo tanto, con todos los commits.

El comando nos muestra la salida que confirma la correcta ejecución del clonado: 

Cloning into 'django'... 
remote: Counting objects: 324353, done. 
remote: Compressing objects: 100% (4/4), done. 
remote: Total 324353 (delta 0), reused 0 (delta 0), pack-reused 324349 
Receiving objects: 100% (324353/324353), 138.51 MiB | 1.01 MiB/s, done. 
Resolving deltas: 100% (228976/228976), done. 
Checking connectivity... done. 
Checking out files: 100% (5199/5199), done. 

Esta salida indica que todos los objetos Git se han descargado correctamente y que los archivos se insertaron en el directorio de trabajo.

Los ejemplos presentes en este repositorio serán ejemplos de habla inglesa. En efecto, todos los repositorios de proyectos libres importantes (o casi) son de habla inglesa para permitir participar a un máximo de personas. Los mensajes de commit serán, pues, en inglés, pero esto no perturbará...

Mostrar las diferencias de contenido

Es interesante poder recuperar los commits, pero a veces lo que el desarrollador busca se encuentra en el contenido mismo de las modificaciones incorporadas por el commit, el directorio de trabajo o el índice. Para esto, debemos utilizar el comando git diff.

El comando git diff muestra una lista de adiciones y eliminaciones de líneas entre dos commits o bien entre las distintas zonas (directorio de trabajo, índice).

Para que los ejemplos tengan sentido, debemos modificar al menos un archivo del repositorio. Los datos con los que el archivo será modificado no son importantes, se utilizarán justo para la visualización de ejemplos. En el caso del depósito de Django, es posible modificar el archivo README.rst para añadir una línea al final (línea de ejemplo para añadir: Yo pruebo el comando git diff). Debemos añadir a continuación esta modificación en el índice.

git add README.rst 

Se debe volver a modificar este archivo cambiando esta última línea (línea de ejemplo: Yo pruebo el comando diff de git).

1. Diferencias en curso en el directorio

Uno de los casos en que git diff es muy utilizado se produce cuando el desarrollador quiere ver los cambios presentes en su directorio de trabajo en relación con su índice. Tener conciencia de estos cambios le permite no añadir al índice aquellos que no desea. Para ver las diferencias entre el directorio de trabajo y el índice, hay que utilizar el comando siguiente:

git diff 

Este comando muestra la siguiente salida:

diff --git a/README.rst b/README.rst 
index 6e9bc5f..9f4dcc9 100644 
--- a/README.rst 
+++ b/README.rst 
@@ -41,4 +41,4 @@ To run Django's test suite: 
 * Follow the instructions in the "Unit tests" section of 
   docs/internals/contributing/writing-code/unit-tests.txt, 
published online at https://docs.djangoproject.com/en/dev/internals 
/contributing/writing-code/unit-tests/#running-the-unit-tests ...

Identificar al autor de una línea de código

Cuando un desarrollador trabaja en un código, a veces puede preguntarse cuál de sus colegas ha trabajado sobre el código en cuestión o cuál ha sido su última modificación de una línea específica. El hecho de conocer que ha modificado la línea permitirá saber que preguntar para obtener más detalles sobre la parte en la que el desarrollador está trabajando.

Por ejemplo, es frecuente preguntarse cuándo, quién y por qué una línea de código se ha añadido o modificado en un archivo. Toda esta información se centraliza en el commit; la única complicación es recuperar el commit que ha modificado esta línea específica.

Para usar git blame sobre un archivo, se debe utilizar la siguiente sintaxis:

git blame minombre_archivo 

Por ejemplo, tomando el archivo README.rst de Django, se debe utilizar el siguiente comando:

git blame README.rst 

Este comando mostrará la siguiente salida truncada (se muestran las dos primeras líneas):

b2cb66bf README  (Adrian Holovaty   2005-07-21 01:37:28 +0000  ==> Linea 
226acf35 README  (Adrian Holovaty   2012-04-27 22:25:08 -0500  ==> Linea 

La salida anterior se ha truncado porque no era muy legible. Los textos ==> línea sustituyen en realidad las dos primeras...

Buscar los commits con el modo pick axe

El modo pick axe no corresponde a un comando de Git, ya que es en realidad un modo utilizable con varios comandos de Git añadiendo un argumento. El modo pick axe permitirá buscar los commits en función de las modificaciones que se añadan. Es decir, que la opción pick axe permitirá saber en qué commits el contenido especificado se ha añadido o eliminado.

El modo pick axe puede ser utilizado con git log, y también con git diff o con el comando git format-patch. Para utilizar esta funcionalidad, se debe añadir el argumento -S seguido de la palabra o de la cadena que se ha de buscar:

git log -S "cadena a buscar" 

Por ejemplo, para buscar los commits del proyecto Django que agreguen o eliminen la cadena «Web framework that», se debe utilizar el siguiente comando:

git log -S "Web framework that" 

Este comando encuentra cuatro commits que añaden o eliminan la cadena buscada.

Este comando permite realizar búsquedas más precisas, directamente en las líneas modificadas o añadidas. También existe la opción -G, que permite buscar los commits a partir de sus modificaciones en función de una expresión regular. Por ejemplo, para buscar los commits que añadan o eliminen las líneas que corresponden a la expresión regular «Web framework.{0, 20}that»...

Eliminar los cambios en el directorio de trabajo

Es frecuente que, durante una prueba o un nuevo desarrollo, el desarrollador desee volver al estado de la última versión del repositorio (apuntado por HEAD). Esto sucede a menudo cuando durante las pruebas el desarrollador modifica muchos archivos, añade algunos al índice y deja esos cambios sin hacer commit. Al final se da cuenta de que no debe hacer commit de ninguna modificación y decide suprimir sus modificaciones volviendo al estado de HEAD.

Para esto, hay que utilizar el comando siguiente:

git reset --hard HEAD 

Cuidado: este comando elimina todas las modificaciones del directorio de trabajo y del índice. Es irreversible; por tanto, debe utilizarse con mucha prudencia. 

Cuando no se ha agregado ninguna modificación al índice o si la modificación debe mantenerse en el índice, es recomendable utilizar el comando git checkout que permite aplicar la versión del índice en los archivos del directorio de trabajo.

La sintaxis a utilizar es la siguiente:

git checkout --archivos 

Introducido con la versión 2.24 de Git, el comando git restore también restaura el estado de los archivos del directorio de trabajo desde el índice. Para hacer esto, use la siguiente sintaxis:

git restore archivo 

Para restaurar el estado del archivo desde HEAD, use git restore con el argumento --staged.

Eliminar las modificaciones del índice

Cuando los cambios ubicados en el índice no presentan mayor interés y deben ser suprimidos (o excluidos del índice), se debe utilizar el comando siguiente:

git reset HEAD 

Sin el argumento --hard, no modificará el directorio de trabajo. Este comando solo pondrá el índice en el mismo estado que la versión más reciente del repositorio. ¡Las modificaciones presentes en el índice se eliminarán de manera irreversible!

Volver a un estado anterior

Varias razones pueden requerir volver a una versión anterior. Una de ellas es probar una versión anterior para comparar algunas funciones del software. También sucede que los desarrolladores quieran probar una versión antigua antes de usar git bisect. El comando git bisect es una herramienta de búsqueda dicotómica en el repositorio. Esta funcionalidad se aborda en el capítulo Las herramientas de Git, en la sección Recuperar un commit erróneo.

Para volver al estado anterior utilizando el hash del commit en el que el desarrollador quiere situarse, se debe utilizar la siguiente sintaxis:

git reset hash_del_commit 

Por ejemplo, si el desarrollador desea volver al proyecto tal como estaba a finales del año 2014, se busca en primer lugar los commits realizados antes del 31 de diciembre de 2014:

git log --before="2014-12-31" -1 

Este comando muestra la siguiente salida:

commit 013c2d8 
Author: Russell Keith-Magee <russell@keith-magee.com> 
Date:   Wed Dec 31 13:21:32 2014 +0800 
 
    Renamed variables to avoid name collision with import of  
django.db.models. 

Luego, se utiliza el comando git reset de esta manera:

git reset 013c2d8 

Esto mostrará la siguiente salida indicando todos los archivos modificados desde el commit mencionado (la salida se ha truncado):

Unstaged changes after reset:   
M  ...

Modificar el último commit

Cuando se siguen las versiones de software, suele ser raro querer cambiar el histórico, pero a pesar de todo puede ocurrir que un desarrollador se dé cuenta de que ha guardado («commit») un poco pronto.

Para poder modificar el último commit, es necesario en primer lugar haber cumplido un imperativo: el commit no debe haber sido enviado (push) a un repositorio remoto (para más detalles sobre los repositorios remotos, debemos consultar el capítulo Compartir un repositorio). En efecto, si el commit precipitado fue enviado y el desarrollador lo modifica, su identificador (en forma de hash) será diferente del servidor y el antiguo commit habrá desaparecido.

El servidor no podrá saber lo que ha pasado realmente. En cambio, si el commit no ha sido enviado a un repositorio remoto, es posible corregir los errores sin problema.

Todo desarrollador se apresura, en un momento u otro, para guardar una modificación. Lleno de confianza, el desarrollador guarda con un commit sus modificaciones antes de darse cuenta de que ha dejado muchas líneas para depurar en el código.

Quiere modificar el contenido de su último commit, así como el mensaje de este que no estaba claro del todo.

Para esto, debe utilizar el comando siguiente:

git commit --amend 

Explicar el funcionamiento de la opción --amend de git commit es más sencillo con un ejemplo....

Ver un resumen de los commits

Git proporciona el comando shortlog para mostrar un resumen de los commits. Este comando puede resultar interesante en muchos casos, por ejemplo:

  • Mostrar una lista de mensajes de commits para un período determinado.

  • Mostrar una lista de mensajes de commits para ramas específicas.

  • Mostrar una lista de mensajes de commits para tags específicos.

  • Mostrar el número de commits por desarrollador.

Como parte de un proyecto que cumple con Git-Flow (método detallado en el capítulo Git-Flow: workflow de empresa) y SemVer (método detallado en el capítulo Las ramas y los tags en la sección Los tags (etiquetas)), por ejemplo, es posible ver todas las correcciones realizadas para la versión 1.12. Un caso de uso común para el comando git shortlog es generar el changelog.

Para proyectos con muchos commits, el comando git shortlog usado sin argumentos es demasiado prolijo y carece de interés. Por otro lado, en el caso de un proyecto pequeño (como el del capítulo Escenario de equipo), el comando git shortlog puede ser representativo de los incrementos en el proyecto de cada desarrollador:

Benito (3):  
     C7 : Branch task_type  
     C10 : Type task + admin  
     C11 : Type task + admin  
  
Dimitri (4):  
     C3 : Creacion de la rama grafico_empleado  ...