OctocatEn mi anterior post explicaba cómo se podía contribuir en proyectos Open Source usando la interfaz de usuario de GitHub. Lo cierto es que es muy sencillo crear un "fork" de un repositorio y trabajar en él hasta el momento en el que queremos aportar una mejora o corregir un bug haciendo un pull request en el repositorio original, como explicaba en ese anterior artículo (léelo antes de continuar si estás familiarizado con el proceso de forking de repositorios en GitHub).

Sin embargo hay una situación muy común posterior al "fork" que puede resultar complicada para los más novatos y de la cual apenas se habla: si tengo un repo clonado mediante un "fork" y pasan las semanas o los meses y quiero sincronizarlo con el proyecto original para tener lo último ¿cómo puedo hacer?.

En realidad existen diversas formas de conseguirlo usando cualquier cliente de Git y jugando con los "remotes" del repo, pero hoy quiero centrarme solamente en el método más sencillo y directo: usando la interfaz de usuario de GitHub.

Voy a mostrarlo con un "fork" que tengo en mi cuenta de GitHub del proyecto de corrector ortográfico Off-Line para Visual Studio Code de Michael Vernier. Hace unas semanas contribuí a ese proyecto añadiendo el corrector ortográfico en español al proyecto original (solo soportaba inglés). Michael aceptó mis cambios y ahora también tenemos corrector ortográfico en español en esta estupenda herramienta.

Si ahora quisiera hacer cambios en mi repo necesitaría obtener la versión más reciente del de Michael y mezclarla con mi repo, conciliando los posibles conflictos que existiesen. Vamos a ver cómo hacerlo desde la propia interfaz web de GitHub.

Los pasos que debemos seguir son los siguientes:

1.- Vamos a nuestro repo y usamos el botón "Compare" que hay a la derecha, encima del código:

GitHub-Act-Fork-001

Los cambios que se muestran son para intentar hacer un "Pull Request" desde nuestro repo al repo original. Generalmente lo que veremos será una pantalla que nos dice que no hay cambios que enviar, ya que una vez aceptado el "Pull request" original no hay nada nuevo que aportar:

GitHub-Act-Fork-002

Pero es que la comparación que necesitamos hacer es la inversa: en este caso no queremos hacer un "Pull Request" de nuestro repo al original (como cuando contribuimos al proyecto), sino que queremos simular justo lo contrario: sería como si el dueño del repo original nos pidiera hacer un "Pull Request" a nuestro repo, justo a la inversa. Es decir, sincronizar nuestro repo con el original implica generar nosotros mismos un "Pull Request" desde el original a nuestra copia.

Nota: si hemos hecho cambios propios en nuestro repo desde que hicimos el "fork" la pantalla anterior los mostrará y tendremos que cambiar a mano las bases de comparación, ya que no tendremos ese enlace. Para ello basta con elegir los repos contrarios en las listas desplegables que aparecen en la página, es decir, poner nuestro repo como repo base, y el original como repo de cabecera (head fork). El resultado es el mismo, pero puede que tengamos algún conflicto en los archivos.

2.- Para ello debemos cambiar la base de comparación. La UI de GitHUb ya nos ofrece directamente la forma de hacerlo usando el enlace que se ve en la figura anterior y que dice "Switching the base" (intercambiar las bases). Al pulsarlo veremos como la comparación se realiza a la inversa, es decir, como si el repo original quisiese hacer un "Pull Request" sobre el nuestro, así que veremos todos los commits que se hayan hecho en el repo original desde que hicimos el "fork" en el nuestro:

GitHub-Act-Fork-003

La interfaz nos informará de si podemos hacer una mezcla limpia sin ningún conflicto (como en la captura anterior) o si existen ciertos conflictos que debemos resolver. También podremos ver los archivos que han cambiado y compararlos con los actuales (vista de diferenciación). De esta forma podemos estar seguros de qué cambios se van a producir, si nos van a dar problemas o no y cómo los gestionaremos.

Si no tenemos problemas de mezcla podemos comenzar con la sincronización.

3.- Así que creamos un "Pull Request" que va a ir desde el repo original al nuestro, para lo cual solo tenemos que pulsar el enorme botón verde que nos proporciona GitHub (ver pantalla anterior).

Antes de iniciar el proceso deberemos escribir una nota sobre la operación, comentando qué vamos a hacer. Esa información será como la que haríamos si el proceso fuera a la inversa en un "Pull Request" normal, y podrá usarse como marcador del commit resultante en nuestro repo una vez termine la operación:

GitHub-Act-Fork-004

4.- La operación se puede realizar de varias maneras, y debemos escoger la forma concreta de materializar el Pull Request. En la página siguiente se nos muestran los commits existentes en el repo original y que vamos a incorporar al nuestro, y se nos ofrecen varias posibilidades de realizar la mezcla (amplia la imagen siguiente y fíjate en el botón desplegable de la parte inferior izquierda):

GitHub-Act-Fork-005

Las opciones disponibles son:

  • Create a merge commit: creará una mezcla desde el repo original conservando todos los commits que existieran en éste. Es decir, tendremos todos los pasos que se hayan seguido en el repo original también en el nuestro, viendo reflejado el proceso completo de cambio también en nuestro repo.
  • Squash and merge: mezcla los cambios del repo original en el nuestro pro generando un único commit que contiene todos los cambios.
  • Rebase and merge:  muy parecido al anterior, pero además hace un "rebase". Mira la documentación de GitHub para conocer mejor los detalles, o mira en el libro Git Pro qué es un rebase.

Según que opción elijamos tendremos un resultado diferente.

Si elegimos la primera opción (quizá la más común, aunque deja un árbol menos limpio), nos pedirá un comentario para el commit de mezcla que se va a generar:

GitHub-Act-Fork-006

Y si elegimos la opción de squash o rebase simplemente nos pedirá confirmación:

GitHub-Act-Fork-008

En cualquiera de los dos casos acabaremos con un repo que tiene el código exactamente igual que el del repo original, es decir, como si hubiésemos hecho de nuevo un "fork", solo que tendremos algunos commits de diferencia en el histórico, según el método que hayamos usado.

Objetivo conseguido :-)

¡Espero que te resulte útil!

💪🏻 ¿Este post te ha ayudado?, ¿has aprendido algo nuevo?
Pues NO te pido que me invites a un café... Te pido algo más fácil y mucho mejor

Escrito por un humano, no por una IA