Los patrones de código abierto no siempre tienen el mayor sentido para los negocios.
Sus objetivos son un poco diferentes: el código abierto favorece la experimentación, donde los negocios tienden a querer centrarse para reducir el tiempo de comercialización.
Las elecciones estructurales tienden a reflejar estos objetivos. Y la decisión de usar una horquilla o ramas para trabajar en las características puede tener un impacto apreciable en la productividad general de un equipo.
La bifurcación tiende a potenciar una evolución divergente de la base de código, lo que la hace ideal para un entorno que busca potenciar una amplia experimentación sobre un tema.
La ramificación, por otro lado, se dirige hacia la evolución convergente. Esto tiende a encajar mejor en los depósitos privados, y por eso es comúnmente utilizado por las empresas y en la mayoría de los contextos comerciales.
Desarrollo divergente vs. Desarrollo convergente
En el mundo del código abierto, es muy común que una base de código, una vez alcanzado cierto punto, se divida en dos proyectos distintos, cada uno con un objetivo diferente (aunque todavía con una ascendencia compartida).
El ejemplo más canónico es la base de código de Linux. Hoy en día, Linux tiene muchas bifurcaciones (i.e. RedHat), todas ellas derivadas de una línea de base histórica compartida.
Lo que es importante señalar es que estos sabores no son sólo caminos de desarrollo temporal – son bases de código con «identidades» distintas, sin intención de reintegrarse entre sí.
Las ramas, por otra parte, siempre se pretende que sean caminos de desarrollo «convergentes». Las ramas son efímeras por su propia naturaleza: una rama no es realmente nada más que un puntero en la cabeza de un linaje de compromiso. Tanto este puntero como la rama son eventualmente destruidos y purgados de la historia de Git después de que la rama se fusiona en origen/maestro.
Forking crea un repositorio completamente nuevo.
GitHub popularizó el «bifurcamiento» con un conveniente botón. Cuando haces un tenedor, estás duplicando todo el repositorio y su historia hasta ese momento.
Al hacer clic en el botón de bifurcación en GitHub, o en cualquier otro host que permita la bifurcación, se completa un comando de clonación de git y se crea un nuevo origen/maestro.
Los tenedores se usan mejor: cuando la intención de la «división» es crear un proyecto lógicamente independiente, que puede que nunca se reúna con su padre.
En el mundo del código abierto, esto sucede todo el tiempo. Un equipo ve una base de código que podría ser un buen punto de partida para su proyecto, y no tienen intención de tratar de fusionar esto de nuevo en la base de código raíz. Así que usan una bifurcación como punto de partida.
Rama
Las ramas se usan más comúnmente para actuar como «zonas de construcción» en una base de código.
Las ramas se utilizan mejor: cuando se crean como lugares temporales para trabajar a través de un rasgo, con la intención de fusionar la rama con el origen.
La mayoría de las ramas son de corta duración; una vez que un rasgo se fusiona en el origen/madre la rama se elimina. Algunas ramas son de larga vida, es decir, Staging, todavía tienen la intención de converger con el origen/maestro.
Para crear una rama, usa git checkout -b new-branch que crea una nueva rama a partir del origen de tu repositorio actual. Los cambios pueden ocurrir mientras trabajas en tu nueva rama.
Costos asociados
Cuando se fusiona una rama, git sólo tiene que ejecutar un diff en el trabajo que se cambió.
El bifurcado es más caro. Al fusionar un tenedor, git tiene que diferenciar efectivamente ambas bases de código completas entre sí, ya que un tenedor representa dos copias completas de la base de código.
Forking crea una copia completa de tu repositorio, mientras que branching sólo añade una rama a tu árbol saliente. El tamaño del archivo de la rama puede variar dependiendo de la rama en la que te encuentres.
Bajo el capó, el git accede fácilmente a los diferentes archivos y confirmaciones dependiendo de la rama que esté usando. Los tenedores inherentemente ocuparán más espacio en tu servidor.
La bifurcación también es operacionalmente más cara
Menos visibilidad: Con los flujos de trabajo centrados en la horquilla, los desarrolladores tienen cada uno su propio repositorio completamente independiente. Esto hace difícil ver en qué está trabajando todo el mundo a menos que puedas ver a todos los tenedores en un lugar.
Si estás usando tenedores, estos cambios vivirán en diferentes reposiciones. Esto significa que no hay un verdadero «espacio de colaboración» para el equipo, sólo un repositorio canónico al que todo el mundo envía los cambios cuando están listos para hacer cambios en el maestro.
Con un flujo centrado en las ramas, todas las confirmaciones existen en un repositorio. Si todos están empujando a su rama, tienes acceso a todos los cambios que ocurren dentro de tu código base.
Mayor riesgo operacional: Con un flujo de trabajo centrado en las sucursales, los desarrolladores pueden empujar sus cambios a un repositorio común con frecuencia (por ejemplo, al final de cada día). Cuando otros desarrolladores actualicen sus copias de trabajo, recibirán estas sucursales.
Un peligro único de un flujo de trabajo centrado en el tenedor, es si un desarrollador trabaja de forma aislada en su propio repo. Aunque no siempre es así, presenta un perfil de riesgo ligeramente mayor para ciertas situaciones, como si el desarrollador deja la empresa o no está disponible temporalmente. El riesgo aquí es la gestión del conocimiento (es decir, otros desarrolladores no necesariamente sabrán dónde está ocurriendo el trabajo).
TL;DR
Un flujo de trabajo centrado en las sucursales tiene sentido para la mayoría de los entornos empresariales. Las bifurcaciones pueden ser un buen patrón para la colaboración y experimentación «pública», pero cuando el caso de uso previsto es que mucha gente trabaje hacia un objetivo unificado, las bifurcaciones tienden a encajar mejor.