Git

Git

Tutorial Git: Comandos avanzados

Git comandos avanzados: uso y ejemplos. Aprende a usar comandos avanzados en Git con ejemplos prácticos y detallados.

Aprende Git y certifícate

Fusiones y rebase: git merge, git rebase (visión general)

Las fusiones y los rebase son dos métodos que sirvevn para integrar cambios de diferentes ramas en Git. Para mantener un historial de commits claro en un proyecto es necesario entender las diferencias entre git merge y git rebase.

Con git merge, se combinan los historiales de dos ramas creando un commit de fusión. Este commit especial tiene como padres a los últimos commits de las ramas involucradas, preservando así todo el historial de cambios y reflejando cuándo las ramas se unieron. Este método sirve para ver de forma clara la evolución del proyecto y las integraciones que se le han hecho.

Por ejemplo, para fusionar la rama desarrollo en main, se puede usar:

git checkout main
git merge desarrollo

Este comando integrará los cambios de desarrollo en main y creará un nuevo commit que une las dos ramas.

De forma contraria, git rebase permite reaplicar los commits de una rama sobre otra, reescribiendo el historial para crear una secuencia lineal de commits. Esto puede servir para que el historial sea más fácil de seguir, porque elimina los commits de fusión y muestra todos los cambios como si hubieran ocurrido en serie.

Para realizar un rebase de la rama feature sobre main, se ejecuta:

git checkout feature
git rebase main

Después de ejecutarlo, los commits de feature se aplican sobre main, y la historia de feature parece que ha partido directamente de main, sin ramas divergentes.

Hay que tener en cuenta que git rebase reescribe el historial, lo que puede causar problemas si la rama se ha compartido con otros colaboradores. Por eso se recomienda utilizar rebase solo en ramas locales o antes de publicar los cambios al repositorio remoto.

Se suele usar git merge cuando se quiere mantener un registro completo de cómo se han integrado las diferentes ramas, lo que es útil sobre todo en proyectos donde es muy importante la transparencia del historial. Por otro lado, git rebase es útil para limpiar un historial antes de compartirlo, para facilitar la lectura.

Depuración de commits: git bisect para encontrar bugs

Para encontrar el origen de un bug en un proyecto con un historial de commits muy grande se puede utilizar git bisect mediante una búsqueda binaria.

El comando git bisect sirve para identificar el commit específico donde se introdujo un error. Este método divide el rango de commits entre un punto conocido como bueno y otro como malo, iterando hasta encontrar el commit que ha causado el problema.

Para iniciar el proceso de bisectado, se utiliza:

git bisect start

A continuación, se indica el estado del commit actual y se establece un punto de referencia bueno:

git bisect bad            # Marca el commit actual como malo
git bisect good <hash>    # Especifica un commit bueno conocido

Git realiza un checkout a un commit intermedio. En este punto, se verifica si el bug está presente. Según el resultado, se informa a Git:

  • Si el bug existe en ese commit:
git bisect bad
  • Si el bug no existe en ese commit:
git bisect good

Este proceso se repite, y Git continúa acotando el rango hasta localizar el commit exacto que introdujo el error. Cada iteración descarta aproximadamente la mitad de los commits restantes, haciendo la búsqueda sea muy rápida incluso en historiales muy grandes.

Por ejemplo, supongamos que después de varias iteraciones, Git indica:

b2f6a27a1f3e4c es el primer commit malo

Este hash corresponde al commit que introdujo el bug, y se puede analizar para identificar y corregir el problema.

Una vez finalizado el bisectado, es importante restablecer el estado del repositorio:

git bisect reset

Se recomienda contar con pruebas automatizadas para ver si el bug está presente en cada commit evaluado. Esto agiliza el proceso al permitir que Git ejecute las pruebas automáticamente. Para ello, se utiliza:

git bisect run ./script_pruebas.sh

En este comando, ./script_pruebas.sh es un script que devuelve un código de salida cero si las pruebas pasan (bug ausente) o un valor distinto de cero si fallan (bug presente). Ahora, Git utiliza estos resultados para marcar automáticamente los commits como buenos o malos durante el bisectado.

Cherry-pick: Traer commits puntuales a otras ramas (introducción)

En ocasiones, es necesario aplicar un commit específico de una rama a otra sin fusionar el resto de cambios. Para esto se utiliza el comando git cherry-pick, que permite traer commits puntuales de una rama a otra de manera selectiva.

El comando git cherry-pick copia el contenido de un commit existente y lo aplica como un nuevo commit en la rama actual. Esto es muy útil cuando se quiere incorporar una corrección de errores o una funcionalidad específica sin afectar otros desarrollos en curso.

Por ejemplo, si se tiene un commit con el hash a1b2c3d en la rama feature que se quiere aplicar a la rama main, se puede hacer lo siguiente:

git checkout main
git cherry-pick a1b2c3d

Este comando posiciona la rama main en el commit más reciente de main y luego aplica los cambios de a1b2c3d como un nuevo commit en main. El commit aplicado mantiene la autoría original, pero tendrá un nuevo hash en la rama de destino.

Si se necesita aplicar múltiples commits, se pueden especificar varios hashes separados por espacios o utilizar un rango de commits. Por ejemplo:

git cherry-pick a1b2c3d e4f5g6h

O para un rango continuo de commits:

git cherry-pick a1b2c3d..e4f5g6h

En este caso, se aplicarán todos los commits desde a1b2c3d hasta e4f5g6h, excluyendo el primer commit e incluyendo el último en el rango.

Puede que durante el cherry-pick surjan conflictos si los cambios realizados en el commit seleccionado entran en conflicto con el estado actual de la rama destino. Si ocurre esto, se detiene el proceso y se permite resolver los conflictos manualmente. Una vez resueltos, se debe continuar con:

git add <archivos_resueltos>
git cherry-pick --continue

Si se decide cancelar el cherry-pick debido a conflictos u otras razones, se puede ejecutar:

git cherry-pick --abort

Esta acción revertirá los cambios y devolverá el repositorio al estado anterior al inicio del cherry-pick.

Se usa mucho git cherry-pick cuando se necesitan aplicar hotfixes o correcciones urgentes a la rama main sin esperar a que el resto de cambios en una rama estén listos para ser fusionados.

Si se va a utilizar git cherry-pick hay que hacerlo con precaución, ya que puede generar un historial de commits muy enrevesado si se abusa de él. Es recomendable mantener un flujo de trabajo ordenado y documentar los motivos de la aplicación selectiva de commits para que otros colaboradores entienda qué ha ocurrido.

Hay que tener en cuenta que el cherry-pick crea nuevos commits en la rama destino con los cambios especificados, así que los hashes de los commits serán diferentes a los originales, por eso, hay que ir con ojo al sincronizar ramas.

Otras utilidades: git blame, git tag

El comando git blame sirve para rastrear la autoría y cambios línea por línea en un archivo dentro de un repositorio Git. Permite identificar quién realizó una modificación específica y en qué commit se introdujo.

Al ejecutar git blame seguido del nombre de un archivo, Git muestra información detallada para cada línea:

git blame archivo.txt

El resultado muestra el hash del commit, el nombre del autor y la fecha de modificación para cada línea del archivo, se usa cuando se necesita contactar al autor original.

También hay opciones adicionales para filtrar y personalizar la salida de git blame. Por ejemplo, para ignorar cambios de formato o espacios en blanco, se puede usar la opción -w:

git blame -w archivo.txt

Además, si se quiere limitar el análisis a un rango específico de commits, se puede utilizar la opción -L para especificar líneas y <rev> para establecer el rango de revisiones:

git blame -L 10,20 archivo.txt <commit_inicial>..<commit_final>

Por otro lado, git tag permite asignar etiquetas a commits específicos para la identificación de versiones en el historial del proyecto. Las etiquetas son utilizadas sobre todo para marcar versiones de lanzamiento o puntos de referencia en el desarrollo.

Existen dos tipos principales de etiquetas en Git: ligeras y anotadas. Las etiquetas ligeras son básicamente punteros a un commit, mientras que las etiquetas anotadas almacenan información adicional como el nombre del etiquetador, la fecha y un mensaje de anotación.

Para crear una etiqueta ligera, se utiliza:

git tag v1.0

Este comando crea una etiqueta llamada v1.0 apuntando al commit actual. Si se quiere etiquetar un commit anterior, se puede especificar el hash correspondiente:

git tag v1.0 <hash_del_commit>

Para crear una etiqueta anotada, que es la práctica recomendada para versiones públicas, se usa el parámetro -a junto con un mensaje de anotación:

git tag -a v1.0 -m "Primera versión estable"

Las etiquetas anotadas incluyen metadatos y son más recomendadas para uso compartido. Para listar todas las etiquetas creadas en el repositorio, se utiliza:

git tag

Si es necesario ver los detalles de una etiqueta anotada, el comando git show es útil:

git show v1.0

Una vez creadas, las etiquetas pueden ser compartidas con otros colaboradores mediante push al repositorio remoto. Por defecto, git push no envía las etiquetas, por lo que es necesario especificarlo:

git push origin v1.0

Para enviar todas las etiquetas a la vez:

git push origin --tags

Es importante adoptar una convención de nombres consistente para las etiquetas, como el uso de versionado semántico (v1.0.0, v1.1.0, etc.), lo que ayuda a comunicar claramente la naturaleza de los cambios entre versiones.

CONSTRUYE TU CARRERA EN IA Y PROGRAMACIÓN SOFTWARE

Accede a +1000 lecciones y cursos con certificado. Mejora tu portfolio con certificados de superación para tu CV.

Plan mensual

19.00 € /mes

Precio normal mensual: 19 €
47 % DE DESCUENTO

Plan anual

10.00 € /mes

Ahorras 108 € al año
Precio normal anual: 120 €
Aprende Git online

Ejercicios de esta lección Comandos avanzados

Evalúa tus conocimientos de esta lección Comandos avanzados con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Todas las lecciones de Git

Accede a todas las lecciones de Git y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Accede GRATIS a Git y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  1. Comprender la utilidad de los comandos avanzados de Git.
  2. Aprender a utilizar comandos avanzados de Git para mejorar la eficiencia en el desarrollo de software.
  3. Familiarizarse con los comandos git cherry-pick, git rebase, git stash, git revert, git fetch, git bisect, git reflog, git filter-branch y git submodule.