Git avanzado
Git ofrece una serie de comandos avanzados que son extremadamente útiles para manejar situaciones más complejas, como rastrear errores, identificar qué desarrollador realizó un cambio específico, trabajar con subproyectos y recuperar commits perdidos. A continuación, desarrollaremos algunos de estos comandos avanzados y su aplicación práctica.
1. Uso de git bisect para encontrar errores #
El comando git bisect es una herramienta poderosa que te ayuda a encontrar cuándo se introdujo un error en el historial del proyecto. Utiliza un algoritmo de búsqueda binaria para identificar el commit que introdujo el problema al revisar de manera eficiente el historial de commits.
Cómo funciona #
-
Inicia la búsqueda binaria con
git bisect:1git bisect start -
Marca el commit actual como malo (donde el error está presente):
1git bisect bad -
Marca un commit conocido como bueno (donde el código funcionaba correctamente):
1git bisect good <commit-id> -
Git cambiará el proyecto a un commit intermedio. En este punto, debes probar si el error está presente en ese commit.
-
Si el error está presente, marca el commit como malo:
1git bisect bad -
Si el error no está presente, marca el commit como bueno:
1git bisect good -
Git continuará dividiendo el rango de commits hasta encontrar el commit exacto que introdujo el error.
-
Una vez identificado el commit, puedes finalizar el proceso con:
1git bisect reset
Ventajas de git bisect:
- Acelera el proceso de encontrar errores en un historial largo de commits.
- Reduce la cantidad de commits que necesitas revisar manualmente.
2. git blame: Rastrear cambios por autor #
El comando git blame se utiliza para identificar quién hizo cada cambio en un archivo específico. Muestra la información línea por línea, indicando qué commit y autor modificaron cada línea del archivo.
Uso #
- Para ver quién modificó cada línea de un archivo:
1git blame <archivo>
¿Qué muestra? #
El comando muestra la siguiente información para cada línea:
- El hash del commit que introdujo el cambio.
- El autor que hizo el cambio.
- La fecha y hora del cambio.
- El contenido de esa línea.
Ejemplo #
1git blame archivo.txt
El resultado será algo similar a esto:
f56a4f20 (Juan Perez 2023-05-12 10:13:42 +0200 1) Línea de código 1
a8f4c872 (María Gomez 2023-04-20 14:25:18 +0200 2) Línea de código 2
3. Submódulos de Git: qué son y cómo usarlos #
Los submódulos de Git permiten incluir un repositorio de Git dentro de otro repositorio. Son útiles cuando deseas mantener un proyecto separado dentro de otro, pero seguir actualizando y controlando versiones del subproyecto de forma independiente.
¿Cuándo usar submódulos? #
- Cuando tienes dependencias entre proyectos que deseas mantener separadas pero vinculadas.
- Para reutilizar un repositorio dentro de varios proyectos sin duplicar el código.
Agregar un submódulo #
-
Para añadir un submódulo en tu repositorio principal, usa:
1git submodule add <url-del-repositorio> -
Git creará un directorio dentro de tu proyecto que contendrá el contenido del submódulo y creará un archivo
.gitmodules.
Clonar un repositorio con submódulos de una sola vez #
1git clone --recurse-submodules <url-del-repositorio>
Si ya lo habías clonado de forma normal:
1git submodule update --init --recursive
4. git cherry-pick: Aplicar commits específicos #
El comando git cherry-pick se utiliza para aplicar un commit específico de una rama a otra sin fusionar toda la rama.
Uso #
1git switch main 2git cherry-pick <commit-hash>
Git aplicará los cambios del commit indicado generando un nuevo commit en main.
Resolución de conflictos en cherry-pick #
Si el commit entra en conflicto, resuélvelo, agrégalo con git add y continúa:
1git cherry-pick --continue
O si decides abortarlo: git cherry-pick --abort.
5. git reflog: Recuperar commits perdidos #
El comando git reflog registra todas las acciones que cambian el puntero HEAD, incluyendo commits, resets, cambios de rama y fusiones. Es tu red de seguridad definitiva cuando crees haber perdido código.
Ver el historial de HEAD #
1git reflog
Verás una lista con hashes e índices (HEAD@{0}, HEAD@{1}, etc.). Si hiciste un git reset --hard por error, puedes restaurar tu rama al punto exacto anterior:
1git reset --hard HEAD@{1}
6. Correcciones limpias en Code Review: git commit --fixup y --autosquash #
Cuando recibes feedback en una Pull Request sobre un commit anterior, en lugar de hacer un commit genérico y un rebase interactivo manual propenso a errores, Git moderno ofrece un flujo automatizado:
-
Realiza la corrección en tu código y haz commit marcando a qué commit previo corrige:
1git commit --fixup <hash-del-commit-original>Git creará automáticamente un commit con el mensaje
fixup! <mensaje original>. -
Aplica automáticamente la fusión sin intervención manual:
1git rebase -i --autosquash origin/mainGit detectará el
fixup!, reordenará los commits y los combinará en el lugar exacto sin pedir confirmaciones manuales.
7. Reutilización de resoluciones de conflictos con git rerere #
RERERE (Reuse Recorded Resolution) es una funcionalidad avanzada que memoriza cómo resolviste un conflicto en un archivo. Si vuelves a encontrarte con el mismo conflicto en futuros rebases o fusiones, Git lo resolverá automáticamente por ti.
- Activar rerere globalmente:
1git config --global rerere.enabled true - Git guardará una "huella" de la resolución en
.git/rr-cachey la aplicará de forma transparente en operaciones posteriores.
8. Inspección de ancestros comunes: git merge-base y comparación en PRs #
Para entender con exactitud matemática qué cambios introduce una rama de características respecto a main (igual que lo muestra GitHub en una PR):
-
Encontrar el commit donde bifurcaron:
1git merge-base main feature/mi-rama -
Comparar con triple punto (
...):1git diff main...feature/mi-rama(El triple punto compara los cambios de
featuredesde el momento en que se separó demain, ignorando los nuevos commits que hayan entrado enmainmientras tanto).
Resumen del tema
Conceptos clave #
git bisect(Depuración por Búsqueda Binaria): localiza el commit causante de una regresión alternando entre estadosgoodybad.git blameygit reflog: auditoría línea a línea y bitácora completa de movimientos deHEADpara rescate de commits perdidos.- Flujo
--fixupy--autosquash: estándar moderno en Code Review para reparar commits pasados sin errores manuales. git rerere: automatización de resolución de conflictos repetitivos en rebases.- Comparación
main...feature: visualización exacta de cambios introducidos en una Pull Request mediante el ancestro común (git merge-base).
Qué debes recordar #
Usa git reflog como red de rescate ante cualquier fallo, automatiza tus correcciones en PRs con git commit --fixup + git rebase --autosquash y activa rerere para no resolver el mismo conflicto dos veces.