24  Referencias

Muchos flujos de trabajo de Git extremadamente útiles requieren que identifiques un punto específico en el historial de tu repositorio, es decir, una confirmación específica.

Hemos explicado en otra parte que cada confirmación está asociada con el llamado SHA, es decir, una suma de verificación SHA-1 de la confirmación misma. Estas cadenas opacas de 40 letras y números no son especialmente agradables para los humanos. La estrategia de afrontamiento básica es trabajar con una forma abreviada del SHA. Es típico utilizar solo los primeros 7 caracteres, ya que esto casi siempre identifica de forma única una confirmación.

Git history annotated with SHAs.

Afortunadamente, hay aún más formas de hablar sobre una confirmación específico, que son mucho más fáciles de entender para los humanos. Estos se denominan “refs” de Git, abreviatura de referencias y, si está familiarizado con el concepto de programación de un puntero, ese es exactamente el modelo mental correcto.

24.1 Referencias útiles

Estas son algunas de las referencias más útiles:

  • Un nombre de rama. Ejemplo: main, wild-experiment. Cuando te refieres a la rama main, eso se resuelve en el SHA de la punta de la rama main. Piense en una referencia de rama como una referencia deslizante que evoluciona a medida que lo hace la rama.

Git history annotated with two branches.

  • HEAD. Esto (casi siempre) se resuelve en la punta de la rama que está actualmente desprotegida.1 Puedes pensar en HEAD como una referencia que apunta a la punta de la rama actual, que a su vez es una ref, que apunta a un SHA específico. Hay dos capas de dirección indirecta. Esto también se llama referencia simbólica.

Git history annotated with HEAD symbolic ref.

  • Una etiqueta. Ejemplo: v1.4.2. Las etiquetas se diferencian de las referencias de rama y de la referencia HEAD en que tienden a ser mucho más estáticas. Las etiquetas no se deslizan por naturaleza, aunque es posible reposicionar una etiqueta para que apunte a un nuevo SHA, si se hace un esfuerzo explícito. El uso más común de una etiqueta es proporcionar una etiqueta agradable para un SHA específico.

Git history annotated with a tag.

Si desea que todo esto sea más concreto, puede usar git rev-parse en el shell para observar cómo las referencias se resuelven en SHA concretos. Aquí está el patrón general:

git rev-parse YOUR_REF_GOES_HERE

Aquí hay algunos ejemplos ejecutados en el repositorio Happy Git:

~/rrr/happy-git-with-r % git rev-parse HEAD
631fee855db49d87f6c2a2cab474e89c11322bf4

~/rrr/happy-git-with-r % git rev-parse main
631fee855db49d87f6c2a2cab474e89c11322bf4

~/rrr/happy-git-with-r % git rev-parse testing-something                       
1eeb91d177b7cb5f9a0b29ebee3e6c0c8ff98f88

Observe que HEAD y main se resuelven en el mismo SHA, ya que la rama main estaba desprotegida en ese momento. testing-something es el nombre de una rama que estaba por ahí.

Estas referencias se pueden usar en todo tipo de operaciones de Git, como git diff, git reset y git checkout:

git diff main testing-something

git reset testing-something -- README.md

git checkout -b my-new-branch main

24.2 Referencias relativos

También hay modificadores que le ayudan a especificar una confirmación relativa a una referencia, p. “la confirmación justo antes de este”.

HEAD~1 se refiere a la confirmación justo antes de HEAD. HEAD^ es otra forma de decir exactamente lo mismo.

Git history annotated with relative refs.

Aquí hay algunos ejemplos ejecutados en el repositorio Happy Git:

~/rrr/happy-git-with-r % git rev-parse HEAD~1
5dacec4950a3746310bb30704417a792302b044a

~/rrr/happy-git-with-r % git rev-parse HEAD^
5dacec4950a3746310bb30704417a792302b044a

Observe que HEAD~1 y HEAD^ se resuelven en el mismo SHA.

Ambos patrones se generalizan. HEAD~3 y HEAD^^^ son referencias válidas y equivalentes.

Debo admitir que no soy un gran admirador de estos atajos de referencia relativa y especialmente cuando retrocedo más de una confirmación. Me preocupa tener algún tipo de error uno por uno según tengo entendido y terminaré apuntando a la confirmación incorrecta.

Herramientas como GitKraken y GitHub hacen que sea extremadamente fácil copiar SHA específicos a su portapapeles. Entonces, cuando necesito una referencia que no sea un simple nombre de rama o etiqueta, casi siempre me apoyo en herramientas fáciles de usar como GitKraken o GitHub para permitirme expresar mi intención utilizando el SHA de interés real. Sospecho que los atajos de referencia relativos son más populares entre las personas que usan exclusivamente la línea de comandos Git y operan bajo diferentes restricciones. En realidad, existe un amplio conjunto de formas de especificar una confirmación de destino que va mucho más allá de la sintaxis ^ y ~ que se muestra aquí. Puede obtener más información en la documentación oficial de Git sobre parámetros de revisión.

En GitKraken, haga clic con el botón derecho o control en la confirmación de destino para acceder a un menú que incluye “Copiar confirmación sha”, entre muchos otros comandos útiles. Si está utilizando otro cliente Git, probablemente haya una manera de hacerlo y vale la pena descubrirla.

GitKraken screenshot showing how to copy a specific SHA.

GitHub también hace que sea extremadamente fácil copiar un SHA en muchos contextos. Esta captura de pantalla muestra solo un ejemplo. Una vez que empiece a buscar esta función, la encontrará en muchos lugares de GitHub.

GitHub screenshot showing how to copy a specific SHA.


  1. ¿Cuándo HEAD no se resuelve en el SHA en la punta de alguna rama? Cuando estás en un estado detached HEAD. ¡CABEZA separada! Eso suena mal, pero no es intrínsecamente bueno o malo. Sin embargo, ES malo estar en un estado de CABEZA separada si no era tu intención y no entiendes el trato. Entras en un estado CABEZA separada cuando verificas directamente una confirmación específica, en lugar de verificar o cambiar a una rama. En manos experimentadas, esto puede ser algo legítimo. Pero mientras tanto, te recomiendo que siempre visites un estado específico en el historial consultando una rama, incluso si eso significa que necesitas crear una rama temporal como holder o time-travel. Para salir del estado CABEZA separada, consulte alguna rama existente, con git checkout main o similar. De lo contrario, el hilo de StackOverflow ¿Cómo puedo arreglar un cabezal separado de Git? aborda muchos escenarios desconcertantes de CABEZA separada.↩︎