git - full - ¿Qué es exactamente lo que queremos decir con "rama"?
git full (2)
Larga historia corta...
Por lo que puedo decir, el término "rama" (en el lenguaje de Git) puede referirse a cosas relacionadas pero diferentes:
- una referencia / puntero no simbólico a un commit,
- el nombre de dicha referencia (por ejemplo, "maestro"),
- el subgrafo del DAG de confirmación del repositorio, compuesto por todas las confirmaciones accesibles desde la confirmación señalada por dicha referencia.
Sin embargo, he visto el término usado para referirse aparentemente a algo distinto de esos tres usos posibles (más detalles a continuación). En un contexto Git, ¿existen otros usos válidos e inequívocos del término "rama" que falta en mi lista anterior?
Más detalles
Después de usar Git durante aproximadamente un año, estoy preparando un breve tutorial para estudiantes de CS. Tengo muchas ganas de concretar la terminología de Git, para evitar cualquier confusión.
Por supuesto, he estado usando las ramas de Git por un tiempo; Me siento cómodo usándolos y me parece increíble el modelo de bifurcación de Git. Sin embargo, todavía encuentro el término "rama" problemático y ambiguo, porque parece referirse a al menos dos cosas diferentes, dependiendo del contexto en el que se usa ... a veces incluso en el mismo tutorial / manual.
Uso 1: rama = puntero / referencia a una confirmación
El libro Pro Git (en 3.1 - Qué es una rama ), después de mostrar el siguiente diagrama,
pasa a definir una rama como
simplemente un puntero móvil ligero a uno de estos compromisos.
Por lo que puedo decir, este es también el significado que tiene "rama" en las páginas de manual de Git.
Estoy perfectamente cómodo con esta definición. Pienso que una rama es solo una referencia que apunta a un compromiso en particular en el DAG, y el "tip commit" de una rama es el compromiso señalado por esa referencia. Hasta ahora tan bueno. Pero espera...
Uso 2: rama = un subgrafo del DAG
El tutorial de Atlassian Git presenta las siguientes ramas:
Una rama representa una línea de desarrollo independiente.
Lo que quieren decir con eso, supongo, es una cadena de confirmaciones. Permítame refinar ese pensamiento ... La única interpretación que tiene sentido para mí es que el término "rama" también puede referirse al subgrafo del DAG de compromiso del repositorio, compuesto por todos los compromisos disponibles desde el compromiso de punta considerado .
Sin embargo, el libro Pro Git, por ejemplo, también contiene el siguiente diagrama (ver 3.4 - Flujos de trabajo de ramificación ),
lo que parece contradecir mi interpretación, porque parece implicar que solo los compromisos C2
- C5
(no C1
) pertenecen a la rama de develop
, y que solo los compromisos C6
- C7
(no C1
- C5
) pertenecen a la rama de topic
.
Considero que este uso es ambiguo y vago porque, si dibujara el DAG en esa etapa, sin saber dónde las referencias de las sucursales han señalado en el pasado, y sin ninguna suposición de ninguna jerarquía entre las tres ramas, todo lo que obtendría es
También encuentro confusos algunos diagramas en otros recursos de aprendizaje de Git. Considere, en particular, lo siguiente (tomado del video de introducción de Lynda.com - Capacitación de Git Essential ):
Aquí, la punta del master
es en realidad 534de
(y los puntos HEAD
al master
), pero la posición de la etiqueta "maestra" en el diagrama es muy engañosa. Lo que se supone que esa etiqueta debe describir en este caso no me queda claro ...
Edición : desde entonces he encontrado esta excelente publicación en el blog de Marc ; La sección de Ramas hace eco de mis comentarios anteriores.
En el segundo caso, nos referimos a "las confirmaciones que son reachable desde la confirmación señalada por la rama".
En el ejemplo de Pro Git, asumiendo que los puntos de la rama topic
para confirmar C7
, esa rama contiene los compromisos C7
, C6
, C5
, C4
, C3
, C2
y C1
. No hay otra noción de que un compromiso esté "en" una rama más que esto en Git, y tiene razón en que podría volver a dibujar el DAG linealmente.
El diagrama de Lynda.com no está muy claro, y sospecho que tienes razón en que es engañoso.
Estás en lo correcto.
Podemos dividir aún más su artículo 1 separando las etiquetas de rama "locales" y "remotas": las ramas locales (etiquetas locales) son nombres que comienzan (internamente, muchos comandos de front-end ocultan esto) con refs/heads/
, mientras que "ramas remotas ", Que también se denominan" ramas de seguimiento remoto ", comience con refs refs/remotes/
remotes refs/remotes/
y luego tenga un componente de ruta más que nombre el control remoto específico antes de la parte que da nombre a la rama. ( Edición, abril de 2018: No me gusta la frase "rama remota" o "rama de seguimiento remoto"; creo que es mejor llamar a estos nombres de seguimiento remoto . Pero hay mucha documentación existente que usa las otras dos frases, por lo que debemos ser conscientes de este uso.)
Por ejemplo, sin duda está familiarizado con refs/remotes/origin/master
, pero si tiene un control remoto llamado bob
, también podría tener refs/remotes/bob/hacks/feep
que rastrea los hacks/feep
.
El nombre de una sucursal local refs/heads/ branch
tiene la característica distintiva de que git checkout
lo pondrá "en" esa rama por defecto, al escribir ese nombre en la referencia HEAD
especial; y una vez que se configura de esta manera, los nuevos compromisos (creados por git commit
, git merge
, git cherry-pick
, etc.) hacen que el nuevo commit SHA-1 se escriba en el archivo de sucursal. (El nuevo compromiso tiene como su padre, o uno de sus padres, la antigua punta de rama).
He intentado usar términos como "punta de rama" para denotar específicamente el compromiso con el cual un nombre de rama como refs/heads/master
points, "nombre de rama" o "nombre de rama local" para referirse al nombre en sí (ya sea prefijado por refs/heads/
or not), y —creo que esta es la menos exitosa— "estructura de rama" para referirse al subconjunto DAG. Sin embargo, dado un DAG con un tenedor y fusionar como este:
o--o
/ /
...-o--o o--o-...
/ /
o--o
Algunas veces quiero referirme a una u otra mitad del pequeño objeto parecido a un anillo de benceno como "una rama" también, y no tengo un término realmente bueno para esto.
(Por cierto, si fueras un topólogo, el hecho de que el diagrama de Atlassian también se pueda dibujar linealmente no te molestaría. Sin embargo, como dice el viejo chiste, los topólogos siguen intentando beber de sus donuts y comerse sus tazas de café ya que cada uno es solo un toro)