Git es una potente herramienta para el control de versiones y tiene una especie de monopolio en este ámbito. Para la mayoría de las tareas cotidianas, Git puede ser sencillo de utilizar gracias a su repetición de comandos. Sin embargo, hay muchas situaciones en las que necesitas algo más que lo básico. Por ello, existen un montón de comandos avanzados de Git que pueden llevar tus habilidades de Git al siguiente nivel.

Esto también te introducirá en varios conceptos de Git con los que normalmente no te encontrarías. Por ejemplo, almacenar temporalmente en lugar de confirmar cambios, volver a basar y añadir archivos a tu staging area. Una vez que los aprendas, puede que descubras que tienes un valor aún mayor para tu equipo.

En esta entrada del blog, introduciremos los distintos commandos avanzados que querrás conocer. Sin embargo, para utilizarlos, necesitas tener a mano algunas habilidades, conceptos e información. Veamos esto primero.

Requisitos Previos Recomendados

Aunque seas capaz de aprender lo básico de Git y entender algunos de los comandos intermedios, como git delete, necesitas más habilidades para manejar los comandos avanzados.

Los consejos que compartimos aquí no serán adecuados para un principiante en Git, así que si el control de versiones, en general, es nuevo para ti, te recomendamos que pases algún tiempo utilizando los comandos básicos a diario antes de buscar añadir más cosas a tu repertorio.

En resumen, aquí tienes una lista rápida de los aspectos que debes comprender:

  • Conceptos básicos de Git como commits, branches, pull requests, etc.
  • Familiaridad con comandos básicos de Git como git add, git merge, git commit, y git push.
  • Para las tareas avanzadas de Git, necesitas ser capaz de navegar por un Terminal.

Es útil tener experiencia trabajando con Git en un entorno de equipo, ya que muchos de estos comandos pueden tener un impacto significativo en una base de códigos compartida. Por ejemplo, puede ser que sólo utilices algunos de estos comandos en un puesto de responsabilidad. Esto significa que debes tener cuidado y saber cuándo utilizas estos comandos.

Git Avanzado: 12 Comandos Poderosos que Querrás Conocer

El resto de este artículo cubrirá 12 comandos Git avanzados diferentes que te llevarán más allá de lo básico y te convertirán en un mago de Git. Empecemos con un comando que puede que utilices más que otros.

1. Rebasing

En primer lugar, rebasing es un potente comando de Git que es una alternativa a una solicitud de extracción. Te permite arrastrar todos los nuevos commits que hagas tras una divergencia de rama a una nueva rama y ranurar los cambios en la punta de la base. Esto te resultará útil si quieres incorporar cambios de otra rama sin crear un commit de fusión por el motivo que sea.

Un caso de uso común para el rebasing es cuando estás trabajando en una rama de características y quieres incorporar cambios de la rama principal sin crear una confirmación de fusión. Ayuda a mantener limpio el historial de tu proyecto, aunque puede tardar más en ejecutarse y puedes ver más errores durante una fusión.

Para volver a basar una rama, utiliza el comando git rebase. Aquí tienes un ejemplo en el que estamos fusionando una rama con otra:

git checkout foo-branch

git rebase main

También puedes listar los commits que vas a liberar y darte la oportunidad de editarlos de antemano. Así, puedes combinar commits, editar mensajes de commit, etc. Puedes utilizar la bandera --interactive o --i para realizar un ‘rebase interactivo’

git rebase --interactive <other-branch-name>

Hablando de eso, combinar confirmaciones en una sola para ordenar un historial de confirmaciones es un caso de uso común para el rebase. Esto puede hacer que tu historial de confirmaciones sea más fácil de leer y entender.

Para hacer esto durante un rebase, sigue la bandera con el número de confirmaciones que te gustaría combinar, lo que combinará las confirmaciones en una sola:

git rebase -i HEAD~3

Esto abrirá una ventana interactiva de revisión, muy parecida a la ventana de confirmaciones, donde puedes elegir y editar las confirmaciones que quieres eliminar:

A partial Terminal window showing the output from a git rebase command. The screen shows three commits, alongside hash IDs and the ‘pick’ command. Underneath, there is a list of commands to help create a custom rebase.
Ejecutar un git rebase en el Terminal.

Tienes una lista de confirmaciones en la parte superior de la pantalla y una selección de comandos en la parte inferior, junto con alguna otra información relevante. La opción por defecto es pick un commit, que lo selecciona como el que quieres utilizar sin cambios.

Sin embargo, hay muchos otros comandos que te ayudarán a navegar por un rebase. Por ejemplo, puedes reformular un commit o combinar varios commits juntos. Para hacer cambios y utilizar los comandos, trabajarás con el editor de tu Terminal. El predeterminado suele ser Vim, lo que significa que necesitas conocer ese editor.

El último paso es guardar tus cambios y luego enviarlos a la rama remota.

2. Reverting, Resetting y Unstaging

Git tiene mala fama cuando se trata de deshacer cambios. Es un proceso difícil en general, con tendencia a generar errores. Sin embargo, si haces cambios en tu directorio de trabajo o en tu área de staging que quieres deshacer, hay algunos comandos de Git que pueden ayudarte.

De hecho, Git te orienta sobre cómo deshacer un archivo si ejecutas un comando git status:

A Terminal window showing the user running a git status command. The output shows the current branch and the changes to be committed. There’s also instructions to unstage a file.
Git te muestra cómo deshacer un archivo durante su salida de estado.

De este modo, puedes eliminar una confirmación de la rama actual y enviarla a otro lugar con facilidad:

git reset HEAD <commit>

Esto tiene el efecto de hacer retroceder tu rama una confirmación, como si eliminaras la última confirmación conocida. Incluso puedes tener un caso de uso en el que quieras restablecer una rama a su estado original. En este caso, puedes restablecer contra el origen remoto, por ejemplo, utilizando git reset --hard origin/main. Sin embargo, ten en cuenta que estos cambios desaparecerán para siempre.

Aunque el comando git checkout es uno de los que utilizarás a menudo y se considera básico, también puedes utilizarlo para deshacer archivos antes de una confirmación:

git checkout -- <filename>

Observa el espacio entre los guiones y el nombre del archivo. Aquí, el comando deshace el archivo que especifiques y descarta los cambios del directorio de trabajo. Ten en cuenta que esto borrará cualquier cambio local que hagas en un archivo. Por ello, comprueba dos y tres veces que no necesitas esos cambios no guardados.

También puedes utilizar git revert los cambios que hagas en una confirmación. Sin embargo, esto no deshace los cambios, sino que crea una nueva confirmación basada en deshacer los cambios dentro de la anterior.

La principal diferencia aquí es que el comando no moverá ningún puntero de referencia a la nueva confirmación, sino que mantendrá las confirmaciones antiguas. Esto es útil cuando quieres deshacer cambios sin eliminarlos de tu historial de confirmaciones.

El comando espera recibir una referencia, y es sencillo revertir la última confirmación:

git revert HEAD

Sin embargo, tienes mucho más margen para restaurar y modificar archivos y confirmaciones. Las dos próximas entradas de esta lista de comandos avanzados de Git se ocuparán de ellas.

3. Restauración archivos a su estado por defecto

Con Git, puedes restaurar fácilmente un archivo a su estado por defecto utilizando un comando bastante nuevo: git restore. De hecho, deberías considerarlo un sustituto de git reset en la mayoría de las circunstancias, ya que ofrece mucha más potencia bajo el capó. Por ejemplo, puedes conseguir el mismo resultado con git restore --staged <filename> que con git reset HEAD.

Sin embargo, el comando puede hacer más cosas: también puede restaurar archivos a sus estados predeterminados. Puedes ver cómo hacerlo si ejecutas también git status :

git restore <filename>

Esto eliminará los cambios del directorio de trabajo como si no hubiera pasado nada. Al igual que con git checkout -- <filename>, debes asegurarte de que no quieres ninguno de los cambios locales, ya que desaparecerán para siempre.

4. Modificación de confirmaciones

Probablemente habrá muchas ocasiones en las que envíes una confirmación y te des cuenta de que has olvidado incluir algo importante. Con Git, puedes modificar fácilmente la confirmación para incluir los cambios que faltan.

Para ello sigue un proceso específico:

  • Primero, haz los cambios en los archivos que necesites para el proyecto.
  • Prepáralos como es habitual utilizando git add.
  • Vuelve a confirmar esos cambios en el área de preparación utilizando un comando diferente para realizar la confirmación:
git commit --amend

Esto modifica el commit original con el nuevo utilizando tu área de staging para ello. Por tanto, asegúrate de que no necesitas la versión antigua del commit, ya que se perderá. También te recomendamos que utilices la bandera --amend con commits locales en lugar de remotos, por razones similares a las que tratamos en otra parte de este post.

También puedes utilizar git commit --amend para editar sólo el mensaje de confirmación con el siguiente comando:

git commit --amend -m "New commit message"

5. Registro de Git

Utilizar el registro de Git es valioso para ayudarte a comprender el historial de un repositorio. Sin embargo, no clasificaríamos el comando git log como avanzado. En su lugar, puedes utilizar varias opciones para filtrar la salida según tus necesidades:

git log

git log --decorate

git log --stat

Por ejemplo, al decorar una entrada del registro se imprimen los nombres de referencia de todas las confirmaciones mostradas. La opción --stat muestra las inserciones y eliminaciones de una confirmación:

A Terminal window showing the output of a git log --stat command. It shows two commits, with the hash highlighted in gold, the author, date of commit, the commit message, and both the number of files changed and inserted.
Ejecutando un comando git log –stat en el Terminal.

También puedes utilizar otras opciones para personalizar la salida del registro, lo que se denomina «limitación de confirmaciones» Por ejemplo, toma los siguientes comandos:

git log --author=<author-name>

git log --grep=<pattern-string>

Aquí puedes filtrar el registro por nombres de autor o patrones de texto específicos. De hecho, puedes combinar varias opciones y banderas para generar un registro con un propósito específico. Por ejemplo, toma este comando:

git log --oneline --author=<author-name> --since=<date> feature-temp

Busca todos los commits con la rama feature-temp de un autor singular desde una fecha especificada, y luego imprímelos utilizando entradas de una sola línea. Ten en cuenta que el parámetro <date> también puede ser una cadena:

--since=”Two weeks ago”

Además, si quieres buscar un archivo concreto en lugar de una rama, puedes ejecutar

git log --oneline --author=bartonfink --since=”5 days ago” -- readme.rm

Este conjunto de ejemplos sólo roza la superficie de lo que puedes hacer con tus registros, pero hay mucho margen para encontrar commits exactos en ellos en función de tus criterios de búsqueda.

6. Hooks Git

Es probable que a veces utilices macros y otros scripts automatizados para ayudar a ejecutar código. Git también incluye este tipo de funcionalidad en forma de ganchos. Estos scripts se ejecutan automáticamente en respuesta a determinados eventos, como confirmaciones o envíos. También hay muchas formas de utilizar ganchos para aplicar formato al código, ejecutar pruebas y mucho más.

Hay dos tipos de ganchos: del lado del cliente y del lado del servidor:

  • Los ganchos del lado del cliente se activan basándose en acciones locales como confirmaciones y fusiones.
  • Los ganchos del lado del servidor se activarán debido a operaciones de red. Por ejemplo, cuando un repositorio recibe una confirmación enviada, entre otros muchos ejemplos.

Git siempre rellenará tu repositorio con varios ganchos de ejemplo una vez que ejecutes un git init. Sin embargo, debes eliminar la extensión .sample para poder utilizarlos:

A Finder window in macOS showing the hidden hooks folder for a Git repo. It contains a host of sample hook script files, each with a .sample extension.
Una carpeta en macOS que muestra los ganchos de ejemplo que Git instala al iniciarse.

Ten en cuenta que sólo puedes ejecutar un tipo de gancho a la vez, aunque es posible utilizar varios scripts a la vez con un poco de trabajo. Por ello, los nombres de tus archivos deben corresponder al tipo de gancho que quieras utilizar basándote en los scripts de ejemplo: pre-commit, update, etc.

Crear un hook Git

Para crear un gancho Git, necesitas crear un script ejecutable en el subdirectorio .git/hooks sin extensión. Seguirá ejecutándose siempre que lo añadas a la carpeta hooks.

Puedes utilizar cualquier lenguaje de programación que desees, siempre que pueda ejecutarse como un ejecutable. Te sugerimos Ruby o Python, pero puedes utilizar Bash, Perl y muchos otros. Todo lo que tienes que hacer aquí es cambiar la ruta a tu intérprete desde la predeterminada de Bash:

#!/usr/bin/env python

A partir de aquí, puedes escribir tu código con normalidad. Por ejemplo, aquí tienes un script prepare-commit en Python que pide al usuario que escriba buenos mensajes de confirmación:

#!/usr/bin/env python

import sys, os

path_commit_msg = sys.argv[1]

with open(commit_msg_filepath, 'w') as f:

f.write("# You’ll need to provide a better commit message than that, buddy!")

Aunque no siempre es necesario, te recomendamos que ejecutes chmod +x .git/hooks/<hook-name> desde la línea de comandos para asegurarte de que puedes ejecutarlo.

En general, los ganchos pueden ser una herramienta poderosa para automatizar tareas repetitivas e imponer las mejores prácticas dentro de tu equipo.

7. Referencias de commits

En Git, identificas los commits por el hash decifrado SHA-1. Aunque es posible referirse a los commits por su hash completo, esto puede ser tedioso y propenso a errores:

bc7623b7a94ed3d8feaffaf7580df3eca4f5f5ca

En su lugar, Git proporciona varias formas de referirse a las confirmaciones utilizando nombres más cortos y memorables. Por ejemplo, puedes utilizar un nombre de rama o etiqueta. Por ejemplo, considera una rama llamada «desarrollar». Aquí tienes un ejemplo en el que nos referimos a la última confirmación de esta rama:

git diff develop..HEAD

Esto muestra las diferencias entre la última confirmación (HEAD) en la rama «desarrollar» y la confirmación actual.

También puedes referirte a una confirmación por su posición relativa en el historial de confirmaciones. Por ejemplo, puedes referirte a dos confirmaciones anteriores a la actual utilizando la abreviatura HEAD~2:

git diff HEAD~2..HEAD

Git también proporciona otras formas de referirse a las confirmaciones, como utilizar el símbolo «@» para referirse a la rama actual o utilizar el símbolo «^» para referirse al padre de una confirmación. Utilizando estas notaciones abreviadas, puedes ahorrar tiempo y evitar errores al trabajar con confirmaciones.

8. Stashing

En circunstancias normales, pensarías que no hay forma de almacenar los cambios que haces en los archivos sin confirmarlos. «Stashing» es la forma de guardado provisional de cambios. Es útil cuando necesitas cambiar de rama o trabajar en una tarea diferente, pero no quieres confirmar tus cambios todavía.

Por ejemplo, si necesitas cambiar de rama para trabajar en algo a mitad del flujo, puedes almacenar los cambios en la rama actual y hacer checkout en la otra. Desde ahí, puedes trabajar en la otra rama, luego confirmar y enviar esos cambios. Luego puedes hacer checkout y recuperar tu trabajo en la rama original.

Para almacenar cambios hay dos formas de hacerlo:

git stash

Esto almacena tus cambios en un nuevo stash, y revierte tu directorio de trabajo a la última confirmación HEAD (el estado en que lo tenías antes de hacer nuevos cambios). Puedes listar los cambios utilizando git stash list, e inspeccionar el alijo utilizando git stash show. Este último comando también puede aceptar cualquier formato que acepte git diff.

Desde aquí, puedes cambiar de rama o trabajar en una tarea diferente. Cuando quieras recuperar tus cambios, ejecuta el siguiente comando:

git stash apply

Esto aplicará los últimos cambios almacenados a tu directorio de trabajo. Sin embargo, ten en cuenta que aún puedes encontrarte con conflictos si cambias demasiado el archivo. Al fin y al cabo, git stash es una solución temporal al problema en cuestión.

También puedes tener varios stashes, y puedes especificar qué stash aplicar utilizando lo siguiente:

git stash apply stash@{n}

El marcador de posición {n} toma un número entero, y stash@{0} representa el último alijo. La documentación oficial de Git incluye otros ejemplos de git stash.

9. Bisecting

Apostaríamos a que todo el mundo se ha encontrado alguna vez con un error o un problema y no tenía ni idea de por dónde empezar a buscar la solución. En estas situaciones, «bisecar» puede ayudarte a identificar rápidamente la confirmación que introdujo el problema.

En pocas palabras, el comando busca errores mediante una búsqueda en tus confirmaciones. Una vez que encuentra el commit infractor, te lo devuelve. La potencia de este comando reside en todos los subcomandos que puedes utilizar.

Para utilizar bisecting, primero tienes que ejecutar el comando git bisect start. Git te llevará al primer commit del historial de tu proyecto.

A partir de aquí, tienes que indicar si ese commit es bueno o malo utilizando los comandos pertinentes:

git bisect good

git bisect bad

Git te llevará entonces al siguiente commit para comprobar su «calidad» Ten en cuenta que también puedes sustituir «good» por «old» y «bad» por «new» para ajustarlo a tu caso de uso específico (aunque no puedes mezclar términos)

A partir de aquí, puedes seguir marcando cada confirmación como buena o mala hasta que encuentres la confirmación que introdujo el error. Sin embargo, no tienes que rastrear todas las confirmaciones: puedes especificar identificadores exactos que te ayuden a acotar y acortar tu búsqueda:

git bisect bad feature-test

En este caso, se utiliza un nombre de rama, pero podría ser una revisión específica utilizando un número entero, una referencia hash, etc. En cualquier caso, una vez que caces y encuentres el fallo, puedes ejecutar cualquiera de los siguientes comandos para volver a tu código más reciente:

git bisect reset

Como con todos los comandos avanzados de Git de esta lista, hay mucho más que digerir, y la documentación de Git será una lectura esencial en este caso.

10. Comparar las ramas

Nuestra entrada sobre referencias de confirmaciones habla sobre el uso de git diff. Ahora es el momento de ver esto con más detalle. A menudo te encontrarás con varias ramas que contienen cambios diferentes. Git te permite comparar las diferencias entre dos ramas utilizando el comando git diff. De hecho, puedes utilizarlo de varias formas, a menudo junto con otros comandos, para investigar y analizar un repositorio.

El comando básico git diff te dará una salida con una visión general de los cambios. Se parece mucho a la salida de una investigación de fusión de confirmaciones:

A portion of the Terminal window that shows a typical git diff output. It shows the files being compared, the index refs, the key and legend for changes between the documents, and the actual changes themselves.
Muestra la salida de una solicitud git diff.

Sin embargo, puedes profundizar en ramas exactas, hashes y muchos más. Por ejemplo, para comparar dos ramas, ejecuta el comando git diff branch1..branch2 y sustituye los marcadores de posición:

git diff feature-branch pre-prod

También puedes comparar las diferencias entre tu rama actual y otra rama:

git diff HEAD..pre-prod

Ten en cuenta que utilizar dos puntos aquí devolverá la diferencia entre las dos puntas de las ramas. En cambio, tres puntos devolverán la diferencia entre el ancestro común de ambas ramas y lo utilizarán para hacer la prueba.

Al igual que git log, puedes limpiar la salida y refinar lo que devuelve. Por ejemplo, git diff --name-only branch1..branch2 sólo comprobará qué archivos difieren y omitirá el contexto:

A portion of a Terminal window that shows how to run a git diff --name-only command. It returns a list of file names only, as per the command.
Ejecutando un comando git diff –name-only en el Terminal.

Puede que encuentres que la salida es difícil de analizar, especialmente si el «diff» es largo. En estos casos, puedes utilizar la opción --color-words:

A Terminal window showing the lengthy output of a git diff request, complete with color references for words. It shows which files are being compared, explicit references to changes and deletion between files, and the changes themselves from the files. Each has color coding to help differentiate them from the rest of the text.
Ejecutar el comando git diff –color-palabras y ver la salida en el Terminal.

En general, git diff puede ser tan potente como otros comandos, especialmente cuando invocas ciertas opciones y refinas qué diferencias devuelve.

11. Aplicar commits individuales

A veces puedes querer aplicar un commit específico de una rama a otra sin fusionar las dos ramas. Git te permite hacerlo utilizando git cherry-pick. Debes utilizarlo con cuidado, pero puedes encontrar que git cherry-pick puede ayudarte en algunos escenarios.

Una situación es cuando tienes ramas de características obsoletas que no fusionas en main o trunk. Podrías utilizar una combinación de comandos (como git log) para desenterrar antiguos commits relevantes y volver a aplicarlos en otro lugar.

Utiliza git log para encontrar la referencia de un commit. A partir de ahí, asegúrate de que estás en la rama a la que te gustaría hacer cherry pick de una referencia. Por ejemplo, supongamos que quieres hacer cherry-pick del commit xxxxxaaaaaa en la rama «trunk«. Primero, comprueba tu rama..

git checkout trunk

…y luego selecciona tu commit:

git cherry-pick xxxxxaaaaaa

Es probable que tu mensaje de confirmación no esté actualizado en muchas ocasiones. Para solucionarlo, puedes pasar la opción --edit al comando. Esto te permitirá proporcionar un nuevo mensaje de confirmación antes de la selección.

12. Potenciando ‘git add’

Para nuestro último comando avanzado de Git, vamos a mostrarte git add. No, no es una errata: este comando fundamental de Git tiene un poder sorprendente bajo su capó.

Por ejemplo, si te encuentras añadiendo archivos individuales al área de preparación, puedes utilizar lo siguiente:

git add -p

La opción -p te permite organizar los cambios de forma interactiva. Puedes revisar los cambios que has hecho en cada archivo y luego elegir los que vas a preparar. Esto podría ahorrarte mucho tiempo y ayudarte a evitar escenificar un cambio no deseado.

Aunque ya sabes que puedes organizar archivos individuales, también puedes especificar un directorio. Por ejemplo, para escenificar todos los archivos del directorio «new-feature«:

git add new-feature

Puede que incluso quieras ver cuál será el resultado de un git add sin llevar a cabo el proceso en su totalidad. Tienes una opción para ello:

git add --dry-run

git add -n

Cuando lo ejecutes, Git te mostrará si añadirá o ignorará los archivos. Hablando de archivos ignorados, también puedes añadirlos al área de preparación si lo deseas:

git add --force

git add -f

Añadir archivos al área de preparación puede ser más complejo que un simple escenario binario de «Añadir o no añadir». Como tal, uno de los comandos más básicos de Git puede cubrir una miríada de eventualidades.

Resumen

Una vez que tengas los comandos básicos de Git en el bolsillo, tendrás el 80 por ciento de lo que necesitas para llevar a cabo las tareas habituales de control de versiones de tu proyecto. Sin embargo, en el 20 por ciento final es donde pueden brillar los comandos avanzados de Git.

Comandos y técnicas como rebasing, bisecting, restaurar archivos, etc., te sacarán rápidamente de un apuro. Y lo que es más, puedes ofrecer un mayor valor a tu equipo y a tu proyecto, y podrías ayudar a agilizar los flujos de trabajo, aumentar la productividad y tener, en general, un mayor efecto como desarrollador.

¿Alguno de estos comandos avanzados de Git formará parte de tu trabajo diario? ¡Háznoslo saber en la sección de comentarios más abajo!

Jeremy Holcombe Kinsta

Editor de Contenidos y Marketing en Kinsta, Desarrollador Web de WordPress y Redactor de Contenidos. Aparte de todo lo relacionado con WordPress, me gusta la playa, el golf y el cine. También tengo problemas con la gente alta ;).