Uso avanzado de referencias: github y pull requests

El viernes pasado (19 de abril de 2013) Jesús Espino dio una charla titulada «Git internals» en Kaleidos. Lo primero que es digno de mención es que una empresa de una «charla interna» e invite a cualquiera que quiera asistir «de fuera». Iniciativas como esta deberían estar a la orden del día en empresas en todo nuestro país. Desde aquí animo a cualquier colega de profesión, trabaje donde trabaje (cárnicas, startups o lo que se tercie) a que comparta lo que sabe, bien sea en un blog, dando charlas en grupos locales o imitando este tipo de iniciativas aunque sea internamente dentro de su empresa. «Hay que subir el nivel» como dice Diego Freniche. Y como me gusta repetirme a mi mismo todos los días: «si quieres cambiar las cosas, empieza cambiando tú y tu entorno».

La charla, que está escrita en TeX, podéis encontrarla en github. Independientemente de los recuerdos que me trajo ver el código fuente (la tesis la escribí en LaTeX) el contenido de la misma no tiene desperdicio. Si os interesa el tema, aunque sea árido, y queréis profundizar en él os recomiendo que leáis el capítulo 9 del libro de Scott Chacon.

Durante la charla se habló bastante de las referencias. Cuando Jesús acabó su magistral intervención, comenté un pequeño truco que aprendí en twitter para poder descargarnos a nuestra máquina los pull requests que recibimos desde github. Llevaba tiempo queriendo sacar un rato para contarlo y Jesús me dio el empujón que me faltaba.

Accediendo a los pull requests

En este artículo usaremos como base el repositorio que utilizamos para la serie de artículos sobre pull requests.

Cuando un usuario hace un pull request desde su fork al repositorio original, github crea en el repositorio orignal una referencia a los commits cuya incorporación se ha solicitado. El repositorio original, el que recibe el pull request, guarda estas referencias en refs/pull/*/head. Recordad que las referencias en git no son más que ficheros que contienen hashes a objetos de git. Estos ficheros están en los servidores de github.

Para poder acceder a esas referencias, y por lo tanto a esos commits, lo único que hay que hacer es decirle a git que se descargue los ficheros con las referencias cuando ejecutamos el comando fetch. Para ello, abrimos el fichero .git/config de nuestro repositorio y modificamos la sección correspondiente al remoto «origin», añadiendo la línea en cursiva que os pongo a continuación:

[remote "origin"]
 url = https://github.com/aprendegit/fork
 fetch = +refs/heads/*:refs/remotes/origin/*
 fetch = +refs/pull/*/head:refs/remotes/origin/pr/*/head

Antes de ejecutar git-fetch, veamos cómo están las referencias remotas del repositorio en SourceTree:

Referencias remotas antes de importar los pull-requests

Referencias remotas antes de importar los pull-requests

Hagamos un fetch:

$ git fetch
From https://github.com/aprendegit/fork
 * [new ref]         refs/pull/1/head -> origin/pr/1/head
 * [new ref]         refs/pull/2/head -> origin/pr/2/head
 * [new ref]         refs/pull/3/head -> origin/pr/3/head

¡Ahí las tenéis! Si actualizáis la pantalla de SourceTree:

El repositorio después de hacer fetch de los pull requests

El repositorio después de hacer fetch de los pull requests

En la captura podéis ver los dos pull requests que ha recibido el proyecto y cómo ha evolucionado cada uno de ellos.

¿Y esto para qué sirve? Pues para probar el código que estáis recibiendo antes de aceptar el pull request, por ejemplo.

Para terminar, quería dar las gracias de nuevo a Jesús por su charla, a Kaleidos por la iniciativa y a Bert Belder (piscisaureus) por colgar el gist con la información que ha dado pie a este artículo.

5 comentarios en “Uso avanzado de referencias: github y pull requests

  1. Joan

    Justo hace unos días me preguntaba como hacer esto, muchas gracias 🙂 Hacéis un trabajo fantástico, seguid así!

    1. alfonso Autor

      Hola Joan

      Me alegro mucho de que el artículo te haya sido útil. Muchas gracias por tu comentario y los ánimos, saber que estáis ahí anima a seguir con la labor.

      Un saludo.

    1. admin Autor

      Hola:

      El comando pull hace dos cosas: un fetch para traerte los commits que te faltan y después hace un merge. Supón que has ejecutado el comando git pull unaramacualquiera. Un posible camino para deshacer el merge es:

      • Guardas en el stash cualquier cambio local que tengas ejecutando git stash
      • Mirando el log, averiguas en que commit estaba tu rama unaramacualquiera antes de hacer pull. Esto puedes mirarlo usando una interfaz gráfica como gitk, sourcetree, o cualquier otra. (supongamos que el commit era 1234567)
      • Haces unaramacualquiera tu rama activa ejecutando git checkout unaramacualquiera
      • Mueves la rama al commit 1234567 ejecutando git reset —hard 1234567
      • Recuperas los cambios locales que has guardado en el stash ejecutando git stash pop.

      Ten cuidado cuando hagas el reset —hard, ya que puedes perder información si no la almacenas en el stash. Si no estás seguro, hazte un zip del repo antes de hacer nada.

      Espero haberte ayudado,

      Alfonso

Los comentarios están cerrados.