17 de enero de 2017

Github: ¿Qué es un Fork y para que sirve?

¿Qué es un fork?

La palabra fork se traduce al castellano, dentro del contexto que nos ocupa, como bifurcación. Cuando hacemos un fork de un repositorio, se hace una copia exacta en crudo (en inglés “bare”) del repositorio original que podemos utilizar como un repositorio git cualquiera. Después de hacer fork tendremos dos repositorios Github para diseñadores web idénticos pero con distinta URL. Justo después de hacer el fork, estos dos repositorios tienen exactamente la misma historia, son una copia idéntica. Finalizado el proceso, tendremos dos repositorios independientes que pueden cada uno evolucionar de forma totalmente autónoma. De hecho, los cambios que se hacen el repositorio original NO se transmiten automáticamente a la copia (fork). Esto tampoco ocurre a la inversa: las modificaciones que se hagan en la copia (fork) NO se transmiten automáticamente al repositorio original.


¿Y en qué se diferencia un fork de un clon?

Cuando hacemos un clon de un repositorio, te bajas una copia del mismo a tu máquina. Empiezas a trabajar, haces modificaciones y haces un push. Cuando haces el push estás modificando el repositorio que has clonado.
Cuando haces un fork de un repositorio, se crea un nuevo repositorio en tu cuenta de Github o Bitbucket, con una URL diferente (fork). Acto seguido tienes que hacer un clon de esa copia sobre la que empiezas a trabajar de forma que cuando haces push, estás modificando TU COPIA (fork). El repositorio original sigue intacto. Lo vamos a ver en breve con un ejemplo.

¿Para qué sirve?

Tiene varios usos. El más común es el de permitir a los desarrolladores contribuir a un proyecto de forma segura.
¿Porqué decimos de forma segura? Imaginaos un super proyecto como puede ser el código fuente de Apache. ¿Cómo se trabajaba antes de existir git? con Subversion o CVS existía un servidor centralizado que tenía dos tipos de usuarios: lo que podían “escribir” en el repositorio (subir cambios al código fuente) y los que sólo podían “leer” el repositorio. Estos últimos sólo podían bajarse el código a su máquina y podían modificarlo sólo en su copia local. No podían subir ninguna modificación al servidor central.
¿Qué tenías que hacer para contribuir? Tenías que solicitar permiso de escritura y que alguien te lo diese. Una vez te lo concedían, ya podías subir tus modificaciones y, por supuesto, liarla si no sabías lo que estabas haciendo. Otra opción era enviar parches, trabajar con ramas… había varias formas pero todas bastante engorrosas.
Además, este procedimiento de dar acceso de escritura a un repositorio centralizado es un poco arriesgado. Siguiendo con el ejemplo que he puesto de Apache ¿cómo sé yo, responsable del repositorio, que esta persona que está a 10000Km de mí en la otra punta del planeta sabe lo que está haciendo? ¿puedo confiar en él?. Al final, contribuir a un proyecto se convertía en una tarea tediosa tanto para el que pretendía contribuir como para el que lo tenía que gestionar. Y no hablemos de lo divertido que era hacer un merge…
Git, al tratarse de un sistema distribuido, resuelve este tipo de problemas de una forma muy elegante a través de los forks. Digamos que Pepito es una persona quiere contribuir al proyecto. Ha encontrado un bug y sabe cómo corregirlo. Como propietario del repositorio me interesa que Pepito pueda enviarme el parche de forma rápida, que no pierda mucho tiempo. Si es así ¡Pepito estará encantado de colaborar con nosotros! ;-). Además, necesito que el proceso sea ágil, no quiero tener que invertir 5 horas de mi tiempo cada vez que tenga que hacer un merge del trabajo que Pepito me envíe. ¿Cómo resuelve git el problema?
  1. Pepito hace un fork de mi repositorio, para lo que sólo necesito darle permiso de lectura.
  2. Pepito trabaja en SU COPIA (fork) del repositorio. Como es suya, puede hacer lo que quiera, la puede borrar, corromper, dinamitar, reescribir la historia del proyecto… nos da lo mismo, es SU COPIA (fork).
  3. Cuando Pepito termina de programar y testear el parche, me avisa de que ya lo tiene y me dice “En la rama parche_de_pepito de MI COPIA (fork), tienes el parche que corrige el Bug XXXX”.
  4. Yo voy a su repositorio, miro lo que ha hecho y si está bien lo incorporo (merge) a mi repositorio, que es el original.
Las ventajas de este proceso son las siguientes:
  1.  Pepito trabaja con SU COPIA. En ningún momento le tengo que dar acceso al repositorio central.
  2. El proceso de incorporación de los cambios de Pepito es muy sencillo. Si no hay conflictos en los ficheros puede que sea tan simple como ejecutar un par de comandos git.
  3. Pepito tiene muy fácil contribuir, no le cuesta esfuerzo.
  4. Yo puedo gestionar muy fácilmente las contribuciones de muchas personas ¡me cuesta muy poco trabajo!
Ahora cierra los ojos e imagina que esto mismo lo pudieses hacer con tus compañeros de trabajo, en tu equipo…

Haciendo Fork de un repositorio en Github

Bueno, vamos a ver esto con un ejemplo práctico. La situación es la siguiente: en nuestra organización, www.aprendegit.com, tenemos un repositorio de un proyecto RubyOnRails y que usaremos a modo de ejemplo. Este repositorio se encuentra en la siguiente URL: https://github.com/aprendegit/fork. Podéis reproducir los pasos que vamos a dar a continuación con vuestra cuenta de github.
Para ayudarnos con el desarrollo de este proyecto, contamos con la ayuda de varias personas:
  1. El usuario aalbagarcia (que soy yo) y que es uno de los administradores del repositorio y de la organización.
  2. El usuario aprendegit-user1, que es un colaborador altruista que quiere ayudarnos con la web.
  3. Vosotros: si hacéis el tutorial y seguís los pasos (tened en cuenta que habrá dos entregas más) acabaréis enviándonos vuestras “mejoras ficticias” a través de un pull request.
No dudamos de las buenas intenciones de aprendegit-user1 ni de sus capacidades y aptitudes (ni de las vuestras tampoco). Aún así, siguiendo las buenas prácticas en el uso de git, aprendegit-user1 sólo tendrá permiso de lectura en el repositorio https://github.com/aprendegit/fork.

No hay comentarios:

Publicar un comentario