Antes de comenzar
Este texto cubre el uso de Git para la colaboración en proyectos y asume el conocimiento de la información tratada en la primera parte de este artículo: Comprender el funcionamiento básico de git y el uso de branches, leer primero para facilitar la comprensión del texto que sigue.
Comenzando
Este artículo utilizará dos personajes ficticios: Teresa, que ha iniciado un nuevo proyecto con un repositorio Git ubicado en /home/teresa/proyecto, y Javier, que tiene un usuario en el mismo sistema y quiere contribuir al proyecto utilizando el directorio /home/javier/proyecto-teresa.
Suponiendo que el repositorio Git de Teresa ya ha sido creado, Javier comienza clonando el proyecto de Teresa en su directorio de contribución:
Javier
cd /home/javier/ git clone /home/teresa/proyecto proyecto-teresa
Entonces Javier hace sus cambios:
Javier
# (Edita los archivos)
git commit -a
Al final Javier le pide a Teresa que aplique las actualizaciones al repositorio original. Bruna así lo hace:
Teresa
cd /home/teresa/proyecto git pull /home/javier/proyecto-teresa
Esto hace que las actualizaciones de archivos realizadas en lo branch master del repositorio de Javier se apliquen a lo branch en lo que estaba Teresa cuando ejecutó el comando. El comando git pull obtiene los cambios realizados desde el repositorio remoto y luego los combina con lo branch actual.
Si ocurre un conflicto, Teresa tendrá que resolverlos localmente en su directorio, Git aún recuperará los cambios pero se negará a combinarlos hasta que se realicen las correcciones.
Teresa puede comprobar los cambios realizados por Javier antes de aplicarlos usando el comando git fetch:
Teresa
git fetch /home/javier/proyecto-teresa git log -p HEAD..FETCH_HEAD
Para ver todos los cambios que Javier ha hecho desde que el proyecto fue clonado, Teresa puede usar el comando:
Teresa
gitk HEAD..FETCH_HEAD
Tenga en cuenta que esta notación de dos puntos .. se puede utilizar tanto con los comandos git log como con gitk. Si Teresa quiere ver tanto los cambios que ella como Javier han hecho desde que el proyecto fue clonado, puede usar la notación ... con 3 puntos.
Teresa
gitk HEAD...FETCH_HEAD
Si Teresa decide que no hay cambios relevantes realizados por Javier, puede seguir trabajando normalmente, mientras que si el historial de Javier muestra algo que realmente necesita, puede ejecutar git pull y seguir trabajando con los cambios recientes realizados por Javier.
Dependiendo del proyecto, puede ser necesario interactuar constantemente con el repositorio remoto. Para facilitar este proceso, es posible crear un alias:
Teresa
git remote add javier /home/javier/proyecto-teresa
# Y entonces
git fetch javier
El uso de un acceso directo permite utilizar el formato javier/master para acceder a información ya obtenida con el comando git fetch, como en el ejemplo:
Teresa
git log -p master..javier/master
El comando anterior muestra una lista de todos los cambios realizados por Javier desde que se realizó el primer clon. Después de analizar estos cambios, Teresa podría aplicarlos con:
Teresa
git merge javier/master
# o buscar en sus branches remotos
git pull . remotes/javier/master
Más tarde, Javier puede querer buscar las últimas actualizaciones de Teresa y lo hace con el comando:
Javier
git pull
Como el repositorio de Javier fue clonado de Teresa, no es necesario proporcionar la ruta al repositorio, Git ya almacena esta información y la usa en el comando git pull.
Javier
# Obtener la ruta del proyecto original
git config --get remote.origin.url /home/teresa/proyecto # Muestra las configuraciones creadas por git clone git config -l # Git mantiene una copia de lo branch de Teresa llamado origin/master git branch -r
# Javier puede seguir trabajando desde otro pc usando ssh git clone teresa.org:/home/teresa/proyecto proyecto-teresa
Explorando lo Histórico
El historial de Git se representa como una serie de commits que pueden visualizarse con el comando:
git log commit 82407449e223ddfd0b8e9ef6df95c8cd156e82b1
Author: Javier <javier@email.org>
Date: Tue May 14 21:37:07 2024 -0300 merge: Comentario añadido al código
El código de la línea commit puede usarse con el comando git show para mostrar más detalles sobre este commit:
git show 82407449e223ddfd0b8e9ef6df95c8cd156e82b1
Usar el principio del código también funciona, siempre y cuando sea único, en este ejemplo usar sólo los números de abajo fue suficiente.
git show 82407
Cada commit tiene un pariente que representa el estado anterior del proyecto.
# Muestra lo último commit de lo branch actual git show HEAD # Lo último commit de lo branch experimental git show experimental # Muestra el pariente de HEAD git show HEAD^ # Pariente del pariente de HEAD git show HEAD^^ # Muestra el cuarto en la jerarquía git show HEAD~4 # Los commits combinados con merge pueden tener más de un pariente # Muestra el primer pariente de HEAD git show HEAD^1 # El segundo pariente de HEAD git show HEAD^2
Asignación de nombres a los commits
Puedes nombrar un commit con:
git tag v2.5 82407
Ahora es posible referirse al commit que empieza por 82407 con el nombre v2.5. Para que este nombre sea válido para otras personas, necesitas crear un objeto tag y quizás firmarlo, busca detalles en el comando git tag usando git help tag.
El uso de nombres puede utilizarse en comandos Git siempre que necesites referirte a un commit, ejemplos:
# Comparar HEAD con commit v2.5 git diff v2.5 HEAD # Iniciar un nuevo branch llamado stable basado en el commit v2.5 git branch stable v2.5 # Restaura el branch y el directorio actuales al estado en HEAD^ git reset --hard HEAD^
Uso de range con git log
# commits entre v2.5 y v2.6 git log v2.5..v2.6 # commits desde v2.5 git log v2.5.. # commits de las dos últimas semanas git log --since="2 weeks ago" # commits desde v2.5 en los que se han producido cambios en el archivo Makefile git log v2.5.. Makefile
Si los branches stable y master divergieron de un punto común hace algún tiempo:
# Lista los commits realizados en master pero no en stable git log stable..master # Lo contrario del comando anterior git log master..stable
El comando git log tiene una debilidad: presenta las confirmaciones en formato de lista. Cuando el historial tiene líneas de desarrollo que divergieron y luego se combinaram de nuevo, el orden mostrado en el comando es irrelevante.
En estos casos, el comando gitk es mejor para visualizar historiales.
# Commits de las últimas semanas con cambios en los archivos de la carpeta drivers
gitk --since="2 weeks ago" drivers/
Uso de la versión junto con los archivos:
# Compara archivos de distintas versiones git diff v2.5:Makefile HEAD:Makefile.in # Visualiza el archivo en una versión específica git show v2.5:Makefile
Buscando
El comando git grep se utiliza para buscar textos(strings) en los archivos del proyecto:
# Busca recursivamente "import" en los archivos del directorio actual git grep "import" # Busca "import" en la version v2.5 git grep "import" v2.5
Concluyendo
Sumando este tutorial y su primera parte debería ser suficiente para tener un control de revisiones distribuido básico para tus proyectos. Dos simples ideas te ayudarán a comprender la profundidad y potencia de Git:
- La base de datos de objetos es el sistema utilizado para almacenar el historial de tus proyectos, archivos, directorios y commits.
- El archivo de índice es un caché del estado del árbol de archivos y directorios y se utiliza en commits, es responsable de verificar los directorios de trabajo y mantener los distintos árboles en una combinación(merge).