¿Qué significa "ramificar es gratis" en Git?


27

¿Qué significa "ramificar es gratis" en Git?

Escucho mucho esto cuando se menciona a Git en comparación con otros sistemas de control de versiones.

No he tenido la oportunidad (?) De tratar con otros ( SVN , etc.), entonces, ¿cómo es la ramificación "costosa" en otros?

Respuestas:


28

La afirmación de que "la ramificación es gratuita en git" es una simplificación de los hechos porque no es "gratuita" per se. Mirando debajo del capó, una afirmación más correcta sería decir que la ramificación es redonkulosamente barata , porque las ramas son básicamente referencias a compromisos . Defino "baratura" aquí como menos gastos generales más barato.

Analicemos por qué Git es tan "barato" al examinar qué tipos de gastos generales tiene:

¿Cómo se implementan las ramas en git?

El repositorio de git, en .gitsu mayoría , consiste en directorios con archivos que contienen metadatos que usa git. Cada vez que crea una rama en git, por ejemplo git branch {name_of_branch}, suceden algunas cosas:

  • Se crea una referencia a la sucursal local en: .git/refs/heads/{name_of_branch}
  • Se crea un registro de historial para la sucursal local en: .git/logs/refs/heads/{name_of_branch}

Eso es básicamente todo, se crean un par de archivos de texto. Si abre la referencia como un archivo de texto, el contenido será el id-sha del commit al que apunta la rama. Tenga en cuenta que la ramificación no requiere que realice ninguna confirmación, ya que son otro tipo de objeto. Ambas ramas y commits son "ciudadanos de primera clase" en términos de git y una forma es pensar en la relación de branch-to-commit como una agregación en lugar de una composición. Si elimina una rama, las confirmaciones seguirán existiendo como "colgantes". Si eliminó accidentalmente una rama, siempre puede intentar encontrar la confirmación con git-lost-foundo git-fsck --lost-foundy crear una rama en el sha-id que encuentre colgando (y siempre que git aún no haya realizado ninguna recolección de basura).

Entonces, ¿cómo hace git un seguimiento de en qué rama estás trabajando? La respuesta es con el .git/HEADarchivo, que se parece a esto si estás en la masterrama.

ref: refs/heads/master

Cambiar ramas simplemente cambia la referencia en el .git/HEADarchivo, y luego procede a cambiar el contenido de su espacio de trabajo con los definidos en la confirmación.

¿Cómo se compara esto en otros sistemas de control de versiones?

En Subversion , las ramas son directorios virtuales en el repositorio . Entonces, la forma más fácil de ramificarse es hacerlo de forma remota, con una sola línea svn copy {trunk-url} {branch-url} -m "Branched it!". Lo que SVN hará es lo siguiente:

  • Copie el directorio de origen, por ejemplo trunk, a un directorio de destino,
  • Confirme los cambios para finalizar la acción de copia.

Deberá realizar esta acción de forma remota en el servidor, ya que realizar esa copia localmente es una operación de tiempo lineal, con archivos que se copian y enlazan. Esta es una operación muy lenta , mientras que hacerlo en el servidor es una operación de tiempo constante. Tenga en cuenta que incluso cuando se realiza la bifurcación en el servidor, la subversión requiere una confirmación cuando se bifurca mientras que git no, lo cual es una diferencia clave. Ese es un tipo de sobrecarga que hace que SVN sea marginalmente menos barato que Git.

El comando para cambiar ramas en SVN , es decir svn switch, es realmente el svn updatedisfraz. Gracias al concepto de directorio virtual, el comando es un poco más flexible en svn que en git. Los subdirectorios en su espacio de trabajo se pueden cambiar para reflejar otra url del repositorio. Lo más parecido sería usarlo, git-submodulepero usarlo es semánticamente bastante diferente de la ramificación. Desafortunadamente, esta es también una decisión de diseño que hace que el cambio sea un poco más lento en SVN que en Git, ya que tiene que verificar cada directorio de espacio de trabajo en qué url remota está reflejando. En mi experiencia, Git es más rápido para cambiar de rama que SVN.

La ramificación de SVN tiene un costo ya que copia archivos y siempre debe estar disponible públicamente. En git, como se explicó anteriormente, las ramas son "solo referencias" y pueden mantenerse en su repositorio local y publicarse a su discreción. Sin embargo, en mi experiencia, SVN sigue siendo notablemente más barato y más eficiente que, por ejemplo, ClearCase.

Es un fastidio que SVN no esté descentralizado. Puede tener múltiples repositorios reflejados en algún repositorio de origen, pero no es posible sincronizar cambios diferentes en múltiples repositorios SVN, ya que SVN no tiene identificadores únicos para confirmaciones (git ha identificado identificadores basados ​​en el contenido de la confirmación). Sin embargo, la razón por la que personalmente comencé a usar git sobre SVN es porque iniciar un repositorio es notablemente más fácil y más barato en git . Conceptualmente en términos de gestión de configuración de software, cada copia divergente de un proyecto (clon, fork, espacio de trabajo o lo que sea) es una "rama", y dada esta terminología, crear una nueva copia en SVN no es tan barato como Git, donde este último tiene ramas "incorporadas".

Como otro ejemplo, en Mercurial , la ramificación comenzó un poco diferente como un DVCS y la creación / destrucción de ramas con nombre requirió confirmaciones separadas. Los desarrolladores de Mercurial implementados más tarde en los marcadores de desarrollo para imitar el mismo modelo de ramificación de git, aunque headsse llaman tipsy en su lugar branchesestán bookmarksen terminología mercurial.


Guau. Muchas gracias por la explicación "cara".
laggingreflex

2
Desde su propia fuente: This command causes a near-instantaneous commit in the repository, creating a new directory in revision 341. The new directory is a copy of /calc/trunk.- Crear la rama es trivial en SVN, a menos que esté haciendo una copia explícita de cada archivo.
Bobson

@Bobson Estaba pensando en reescribir los bits en la ramificación, ya que estoy haciendo muchas maniobras con respecto a eso, pero mi punto sigue siendo que se requiere un compromiso para crear una rama, mientras que en Git no lo es. En mi humilde experiencia, todavía siento que cambiar de sucursales en SVN es más lento que en Git, pero no puedo señalar ninguna razón específica por la cual.
Spoike

2
@Spoike - Cambio, sin duda. Y definitivamente se requiere un compromiso. Hice una edición para aclarar el bit con el que tuve un problema. Siéntase libre de revertirlo si lo prefiere.
Bobson


10

En Git, una rama es solo una referencia a un compromiso con el repositorio local. Crearlo es muy barato, no hay red en absoluto. No del todo gratis (tienes que escribir un comando), pero muy cerca.

La ramificación no es particularmente costosa en SVN: es solo una copia, que es una confirmación muy barata. SVN tiene un modelo de repositorio central, por lo que es un acceso a la red, pero no uno horrible.

En el venerable CVS, por otro lado, la ramificación es MUY costosa. Básicamente, las ramas CVS implican agregar una etiqueta, pero en CVS eso significa que TODOS LOS ARCHIVOS AFECTADOS deben modificarse. Cada archivo se reescribe para incluir la nueva etiqueta. Eso es terriblemente caro. Y si su repositorio es grande, también es terriblemente lento. De hecho, si estás en un gran proyecto, es lo suficientemente lento como para que algunas personas eviten hacer ramas si pueden.


44
Con Git, es incluso menos que una confirmación: una rama es solo una etiqueta. Y SVN suena tan caro como CVS, ya que ambos copian todos los archivos.
Izkata

8
@Izkata: si vemos desde el punto de vista del usuario, sí, todos los archivos se copian, desde el punto de vista de la implementación (y el rendimiento), no, solo se agrega un registro sobre la copia.
maxim1000

@Izkata es demasiado para comentar, mira mi respuesta.
gbjbaanb

66
@Izkata SVN crea punteros y referencias, no copia todo.
Aaron McIver

2
Una rama de Git no es una confirmación, es solo una referencia a una confirmación que se puede mover libremente a otras confirmaciones. Piense en un repositorio de Git como solo un árbol de commits, y las ramas como notas adhesivas que se pueden mover libremente a diferentes commits en ese árbol.
40XUserNotFound

5

La ramificación de SVN es tan gratuita como la de Git. Es solo un poco de datos de limpieza que dice dónde comienza la sucursal, sin cambios en los archivos almacenados. Una 'copia' en SVN es como agregar un enlace simbólico a un directorio Unix. Tenga en cuenta que la rama SVN no requerirá un viaje de red hasta que confirme los cambios de su copia de trabajo (pero no tiene mucho sentido tener un SCM si no se compromete fuera de lugar en algún momento).

Tenga en cuenta que una rama de Git también implicará un poco de limpieza, como agregar esa etiqueta internamente, que tendrá que almacenarse en algún lugar cuando realice la confirmación. No es gran cosa, por eso se llama 'gratis'.


5

Es 'gratis' (en este contexto, 'gratis' realmente significa rápido y fácil y no ocupa espacio) porque en algunos sistemas de control de versiones anteriores una rama era una copia completa del código en ese punto, por lo que las ramas tomaron mucho espacio y fue fácil terminar con muchas versiones completamente completas del software, que luego tomaron la gestión. En otros, no era una copia completa del código, pero todos los archivos aún tenían que modificarse para una etiqueta, por lo que era lento y doloroso ('costoso').

Las ramas de git son esencialmente etiquetas que apuntan a una confirmación y, por lo tanto, evitan los problemas anteriores.


1

Otro aspecto de "gratis / barato / costoso" tiene que ver con el costo en términos de recursos del desarrollador para hacer frente a las consecuencias posteriores de la ramificación; es decir, el proceso de fusión de cambios de sucursales.

Y aquí, fusionar sucursales en sistemas DVCS como Git y Mercurial es más fácil que en sistemas más antiguos ... porque los sistemas DVCS hacen un trabajo mucho mejor al rastrear el historial de las versiones en el gráfico; es decir, donde se ha producido una fusión previa. Esto hace que las fusiones sean más precisas, reduce conflictos innecesarios y ... hace que la fusión subjetivamente sea "más fácil" o "menos aterradora" para los desarrolladores involucrados.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.