¿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 git 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?
- Pepito hace un fork de mi repositorio, para lo que sólo necesito darle permiso de lectura.
- 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).
- 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».
- 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:
- Pepito trabaja con SU COPIA. En ningún momento le tengo que dar acceso al repositorio central.
- 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.
- Pepito tiene muy fácil contribuir, no le cuesta esfuerzo.
- Yo puedo gestionar muy fácilmente las contribuciones de muchas personas ¡me cuesta muy poco trabajo!
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:
- El usuario aalbagarcia (que soy yo) y que es uno de los administradores del repositorio y de la organización.
- El usuario aprendegit-user1, que es un colaborador altruista que quiere ayudarnos con la web.
- 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.
Si no tiene permiso de escritura, el usuario aprendegit-user1 podrá clonar el repositorio (porque es público) pero no podrá hacer un push. De poco le va a servir clonarlo y trabajar sobre él si luego no va a poder hacer un push ¿qué debe hacer? Hacer un fork.
El usuario aprendegit-user1 va a github, accede con su usuario y contraseña y abre la URL del repositorio original https://github.com/aprendegit/fork:
En la página del repositorio, aprendegit-user1 hace clic sobre el botón fork. Al hacer clic, Github va a crear un nuevo repositorio en su cuenta que es una copia del repositorio aprendegit/fork:
Cuando el proceso de forking termina (puede durar varios minutos si el repositorio que estamos bifurcando es muy grande) aprendegit-user1 acaba en la siguiente pantalla:
Este repositorio es una copia del original (https://github.com/aprendegit/fork). Si comparáis la historia de los dos repositorios veréis que es idéntica.
Este nuevo repositorio (https://github.com/aprendegit-user1/fork) es el que nuestro usuario aprendegit-user1 va a utilizar para trabajar y, cuando termine, enviarnos sus modificaciones.
aprendegit-user1 empieza a colaborar con nosotros
La primera tarea que aprendegit-user1 va a hacer como colaborador nuestro es modificar la página de inicio añadiendo nuestro logo. Para ello, clonará su fork y trabajará sobre él como si fuese un repositorio normal. Dado que el fork está en su cuenta, él es el propietario y como tal podrá hacer push sin ningún problema. Recordad que al repositorio original (https://github.com/aprendegit/fork) este usuario no puede hacer push.
Al cabo de unos minutos, aprendegit-user1 ha clonado su repositorio (https://github.com/aprendegit-user1/fork) en su máquina, ha añadido el logo y ha hecho un push a su fork:
Si volvéis al repositorio original (https://github.com/aprendegit/fork) veréis que este sigue igual, las modificaciones que aprendegit-user1 ha subido están sólo en el fork de aprendegit-user1.
Misión cumplida: aprendegit-user1 ya está trabajando en su repositorio sin preocuparnos ninguno de los dos de que algo salga mal.
Esto es todo por hoy. En la siguiente entrada veremos qué ocurre si después de que aprendegit-user1 ha hecho un fork, nuestro administrador (aalbagarcia) sube cambios al repositorio original ¿cómo actualiza aprendegit-user1 su fork?.
¡Happy gitting!
Que bueno es leer chino con traducción simultanea 😉
Recuerdo la primera vez que que trabajé en un entorno con SVN me costó comprender los términos y funcionamiento. Desde que existe github la cosa es mas fácil, aunque sigue siendo compleja para los que no somos programadores puros.
Gracias por confirmar parte de lo que sé y por ampliar algunos términos.
Espero con ganas el siguiente post para aprender a traer los cambios del Repositorio original a mi fork usando github app, terminal o sourcetree 🙂
Hola Pancho:
Ya tienes la segunda entrega del artículo: https://aprendegit.com/mantener-tu-fork-al-dia/
Espero que cumpla con tus expectativas 😉
Pingback: Mantener tu fork al día | Aprende GIT
Pingback: ¿Qué es un pull request? | Aprende GIT
Acabo de descubrir este blog y me ha encantado.
Simplemente quería daros las gracias por el trabajo.
Un abrazo
Hola Jorge:
Muchas gracias por tu apoyo. Llevo unos días desaparecido, en breve recuperaré la actividad.
Alfonso
Muy bien explicado para los que empezamos a trabajar con github
Hace unos días me hice una cuenta, pero la deje botada al no entender como funcionaba.
Gracias a este blog, empezare a experimentar haciendo algún fork de proyectos que me interesen
gracias 🙂
Hola Marcelo:
Gracias por el comentario, me alegro de que los artículos te hayan animado a experimentar con los forks. Aunque al principio es un poco chocante, una vez lo entiendes te das cuenta de que tiene mucho sentido. Ánimo y a contribuir a la comunidad 😉
¡Seguimos en contacto!
Que excelente explicación! Mejor no se puede! Saludos!
¡Gracias y saludos para tí también! Espero verte por github haciendo pull requests pronto 😉
Realmente excelente blog, me animo a aprendergit con este blog, espero poder aportar los conocimientos básicos, que he logrado obtener ya y mas con el tema de los forks que aun no logro entenderlos por completo. Mil felicitaciones al compañero que mantiene el blog y a seguir compartiendo sus conocimientos.
Por ahora dejo mi fork mejorado:
https://github.com/WuilmerBolivar/fork/
Tengo algunos cambios en el README para que sea vea un poco mas organizado.
Dentro de poco haré un pull request.
Espero los cambios sean aceptados.
Luego continuare aprendiendo con el blog. De nuevo gracias.
¡Cambios aceptados!. Y muchas gracias por tus comentarios.
muchas gracias x la super explicación de estos puntos..ahora ya se bien de lo que se trata cada uno
¡Gracias a tí!
Pingback: ¿Qué es un fork y cómo trabajar en Github? | GeeksRoom
Pingback: ¿Qué es un fork y cómo trabajar en Github? | Enfoque IT
Pingback: ¿Qué es un fork y cómo trabajar en Github? | Blog actuales.es
Tengo una consulta,
En mi caso necesito tomar como base un proyecto existente para iniciar el mío. Es decir, los aportes no regresaría al repositorio original.
¿Es correcto usar el fork en estos casos? ¿Que sucede cuando el repositorio original se borra, se borran los forks también?
Saludos!
Hola Ezequiel:
Si necesitas o te interesa mantener la historia del repositorio, la respuesta es sí. Si no te interesa la historia del repositorio para nada y estás seguro de que no vas a necesitar volcar cambios al repositorio original, otra opción es crear un repo vacío, copiar el código del que vas a partir y empezar de cero haciendo un push. Hay otras formas de hacer esto mismo, esta es una de ellas.
Con respecto a tu última pregunta, depende. Si el repositorio el privado, la respuesta es que sí: al borrar el original se borran los forks. Si es público la respuesta es que no (https://help.github.com/articles/deleting-a-repository).
Saludos
Una consulta empeze hace poco a trabajar en un repositorio privado al cual me agregaron, como nunca habia usado github desde la web, como no recordaba le di a fork sin querer (creyendo que asi se me clonaba al escritorio jaja) logico despues lo hise de la manera correcta, pues ahora quisiera eliminar ese fork ya que trabajo directamente en el repo original, puedo borrarlo sin problemas? y sin perder ni generar un error con el otro repositorio? Saludos desde argentina!
Hola Ariel:
Sí, puedes borrar tu fork sin problemas. Eso sí, ten en cuenta que una vez lo borres este desaparece de github y no es recuperable. El repositorio original no se borrará.
A modo informativo, en este enlace tienes la política de que sigue github con respecto a qué le pasa a los forks de un repositorio privado cuando borras el repositorio original (https://help.github.com/articles/what-happens-to-forks-when-a-repository-is-deleted-or-changes-visibility). Los forks de los repositorios públicos permanecen aún cuando se borre el repositorio original.
Un saludo a tí desde España, y gracias por tus comentarios.
Alfonso
Habia estado buscando un artículo que estuviese enfocado en alguien como yo que ademas de no entender los terminos de Github tampoco entendiera para que sirven y Alfonso los abordó muy bien aquí con un lenguaje sencillo. Ahora si estoy empezando a hacer cosas utiles con mi cuenta de Github y me he propuesto leer todos los articulos de este sitio. Gracias Alfonso!!
Hola Juan:
Gracias a tí por tus comentarios y tu feedback. Me alegro de que el artículo te haya sido de utilidad.
Un saludo,
Alfonso
Hola.
Tengo una duda. Si lo que se quiere es no solamente modificar los archivos, sino crear uno nuevo, ¿cómo se hace?. Porque veo por ahí que dicen de copiar el archivo en cuestión usando «cp» pero en ningún lado veo dónde introducir ningún comando, ni ninguna opción gráfica para copiar un archivo en concreto. Es para traducir una página y en teoría se tiene que copiar la principal y llamar a la nueva igual pero cambiando el final poniendo el idioma en cuestión. Un ejemplo, index.rst -> index.rst.es.
Gracias de antemano!
Hola. Lo tienes que hacer en dos pasos, es decir, tienes que primero copiar el fichero (usando el comando cp o el gestor de ficheros que más te guste) y luego hacer un git-add -> git-commit como harías con cualquier fichero nuevo que quieres añadir a tu repositorio.
Si es una operación que haces a menudo, aquí tienes un pequeño comando que hace esto: git-cp (https://github.com/gitbits/git-cp).
Un saludo.
Ya, pero ¿dónde pongo el comando?. Yo estoy dentro de la web, tengo hecho el fork del proyecto, veo las carpetas, me meto en «pages» y ahí veo las páginas, veo la «index.rst» y picando sobre ella puedo editarla, etcétera. Sé lo de branch, add, commit, pull request, merge… pero no veo dónde meter comando alguno o la manera de copiar la dichosa página. ¿Lo de gestor de ficheros te refieres a github for windows?. Me he instalado ese programa también y clonado el proyecto en local, ahí manualmente puedo acceder desde el sistema operativo a la carpeta «pages» y copiar y pegar la página en cuestión, pero no sé si ese modo es el correcto o no.
Gracias por responder.
Mmmmm, vamos a ver. Tienes dos formas de hacerlo
Forma 1: haciendo un fork y luego un clone
Después de hacer el fork en github, haces un git-clone de tu fork. Una vez los tienes en tu máquina, haces el copiado del fichero, lo editas, luego un git-add, git commit, git push y lo envías a tu fork. Como bien dices en tu comentario, este es «un» modo correcto de proceder.
Forma 2: en github
Esto mismo lo podrías hacer directamente en github utilizando su interfaz web. Ahora mismo no sé si te permiten copiar un fichero, lo que sí te permiten es crearlo vacío así que podrías crearlo, pegar el contenido del fichero y luego modificarlo. Todo directamente desde la web. Si lo haces así no hace falta que clones y luego hagas add/commit/push. Importante que entiendas que el resultado será prácticamente el mismo. Eso sí, editar texto en la interfaz de github puede ser muy engorroso dependiendo de qué quieras hacer. Si es traducir cadenas de texto esta solución te podría servir. Si quieres editar código fuente la cosa puede ser divertida 😉
¿te he aclarado un poco más la cuestión?
Buenas.
Sí, ya tengo claro que los métodos son válidos. Esta tarde después de publicar el comentario anterior pensé en crear archivo nuevo (que eso sí lo permite la web) y pegar ahí la página principal, pero nuevamente me venía la duda de si sería válido hacerlo así o no.
En principio traducir la página no se hace mal desde la propia web, aunque podrían mejorarlo porque tanta línea de esa manera no es muy amigable. Supongo que la gente que se dedica a editar código se lo baja en local en el ordenador y lo hará con su editor preferido y luego lo subirá.
Muchas gracias por aclarar el asunto.
Gracias por el tutorial, me podrías orientar en cuanto a la diferencia de utilizar un fork en lugar de un branch para el trabajo colaborativo en un proyecto?
Muchas felicidades, tengo que decir que me ha servido mucho leer esto.
Me gustaría aprender de GIT, soy un estudiante y tengo algunos proyectos que estoy trabajando. Pero no sé como empezar.
Existe alguna buena forma para empezar? O por donde empiezo?
Saludos.
Hola soy yo nuevamente. Después de ver sus vídeos me ha quedado claro cómo empezar con Git.
Nuevamente muchas felicidades y gracias por compartir sus conocimientos.
Saludos desde Cancún, México.
Hola Alfonso, muy buena la información que compartis, vi tus videos y están muy bien explicados!!.
Siempre trabaje con Subversion pero git me resuelve todos los problemas que tenia con svn.
Saludos desde Buenos Aires, Argentina.
Hola, muchisimas gracias por los aportes, recién descubrí esta web y no tiene desperdicio, confirmo cosas que ya sabía y descubro muchas nuevas y de forma muy clara.
Felicidades y gracias de nuevo por los aportes.
disculpen y si quiero salirme de ese fork, ya que yo me confundi y accedi a uno que era parecido al que me habian comentado. 🙁
me esta resultando muy util tu blog. pero tengo una duda un poco absurda….
en el caso de que dentro de mi mismo usuario del SO, quisiera cambiar entre dos usuarios de git (uno con una version, y el otro con un fork de esa version), como podría hacerlo?
obtengo este error:
$ git push
remote: Permission to username1/proyect.git denied to usuario2.
fatal: unable to access ‘https://github.com/username1/proyect/’: The requested U RL returned error: 403
Excelente articulo, aunque pensadolo bien digamos si fuera dueño o propietario del repositorio de Instagram y alguien hace un fork del repositorio para poder hacer un merge luego de alguna funcionalidad en especifico, o de algun bug que haya solucionado esta persona, pienso que como propietario deberia hacer el merge sobre un commit porque si tiene muchos commits analizar cada uno y tratar de hacer el merge conllevaria tiempo en el caso de que exista conflictos.
Excelente la explicación y blog!!!
Estoy empezando con una instalación de GItLab onprimise, en el datacenter donde trabajo. Tengo 2 usuarios. 1 administrador y otro dev.
Necestio hacer a un repositorio base, varios fork con distintos nombres. Este repositorio base es un código fuente que es base para todas mis app. Los fork con diferentes nombres, son los diferentes proyectos de varios clientes.
Gitlab solo me deja hacer 1 fork, no me deja hacer mas de 1 sobre el mismo usuario. Como puede ser posible de hacer mas de 1 fork en el mismo usuario???? Es posible???
Gracias.. adelante con los artículos de GIT