Saltar al contenido

¿Dónde comienza una rama de Git y cuál es su longitud?

Hola usuario de nuestro sitio, hallamos la solución a lo que andabas buscando, continúa leyendo y la encontrarás aquí.

Solución:

En Git, se podría decir que cada rama comienza en la confirmación raíz, y eso sería literalmente true. Pero supongo que eso no es de mucha ayuda para ti. Lo que podría hacer en su lugar es definir “el inicio de una rama” en relación con otras ramas. Una forma de hacer esto es usar

git show-branch branch1 branch2 ... branchN

y eso le mostrará la confirmación común entre todas las ramas especificadas en la parte inferior de la salida (si hay, de hecho, una confirmación común).

Aquí hay un ejemplo de la documentación de Git del kernel de Linux para show-branch

$ git show-branch master fixes mhf
* [master] Add 'git show-branch'.
 ! [fixes] Introduce "reset type" flag to "git reset"
  ! [mhf] Allow "+remote:local" refspec to cause --force when fetching.
---
  + [mhf] Allow "+remote:local" refspec to cause --force when fetching.
  + [mhf~1] Use git-octopus when pulling more than one heads.
 +  [fixes] Introduce "reset type" flag to "git reset"
  + [mhf~2] "git fetch --force".
  + [mhf~3] Use .git/remote/origin, not .git/branches/origin.
  + [mhf~4] Make "git pull" and "git fetch" default to origin
  + [mhf~5] Infamous 'octopus merge'
  + [mhf~6] Retire git-parse-remote.
  + [mhf~7] Multi-head fetch.
  + [mhf~8] Start adding the $GIT_DIR/remotes/ support.
*++ [master] Add 'git show-branch'.

En ese ejemplo, master está siendo comparado con el fixes y mhf sucursales. Piense en esta salida como una tabla, con cada rama representada por su propia columna y cada confirmación obtiene su propia fila. Las ramas que contienen una confirmación tendrán un + o - aparecen en su columna en la fila para esa confirmación.

En la parte inferior de la salida, verá que las 3 ramas comparten un compromiso de ancestro común, y que de hecho es el head cometer master:

*++ [master] Add 'git show-branch'.

Esto significa que ambos fixes y mhf se ramificaron de ese compromiso en master.

Soluciones alternativas

Por supuesto, esa es solo una forma posible de determinar una confirmación base común en Git. Otras formas incluyen git merge-base para encontrar ancestros comunes, y git log --all --decorate --graph --oneline o gitk --all para visualizar las ramas y ver dónde divergen (aunque si hay muchas confirmaciones, se vuelve difícil muy rápidamente).

Otras preguntas del póster original

En cuanto a estas preguntas, tenías:

Está comprometido D un miembro de ambas ramas o podemos decidir claramente si pertenece a branch-A o branch-B?

D es un miembro de ambas ramas, es un compromiso de ancestro para ambas.

A los supervisores a veces les gusta saber cuando se ha iniciado una rama (normalmente marca el inicio de una tarea)

En Git, puede reescribir el historial de todos los árboles de confirmación y sus ramas, por lo que cuando una rama “comienza” no es tan inamovible como en algo como TFS o SVN. Usted puede rebase se ramifica en cualquier punto en el tiempo en un árbol Git, ¡incluso poniéndolo antes de la confirmación raíz! Por lo tanto, puede utilizarlo para “iniciar” una tarea en cualquier momento del árbol que desee.

Este es un caso de uso común para git rebase, para sincronizar las ramas con los últimos cambios de una rama ascendente, para impulsarlos “hacia adelante” en el tiempo a lo largo del gráfico de confirmación, como si “acabara de empezar” a trabajar en la rama, aunque en realidad haya estado trabajando en ella. por un momento. Incluso podría hacer retroceder las ramas en el tiempo a lo largo del gráfico de confirmación, si lo desea (aunque es posible que tenga que resolver muchos conflictos, dependiendo del contenido de la rama … o tal vez no lo hará). Incluso podría insertar o eliminar una rama desde la mitad de su historial de desarrollo (aunque hacerlo probablemente cambiaría los valores de confirmación de muchas confirmaciones). Reescribir el historial es una de las características principales de Git que lo hace tan poderoso y flexible.

Esta es la razón por la que las confirmaciones vienen con una fecha de creación (cuando la confirmación se creó originalmente) y una fecha de confirmación (cuando la confirmación se confirmó por última vez en el árbol de confirmaciones). Puede pensar en ellos como análogos para crear fecha-hora y fecha-hora de última modificación.

A los supervisores a veces les gusta saber …a qué rama pertenecen algunos cambios (para obtener el propósito de algún cambio, si fue necesario para el trabajo).

Nuevamente, debido a que Git le permite reescribir el historial, puede (re) basar un conjunto de cambios en prácticamente cualquier rama / confirmación en el gráfico de confirmación que desee. git rebase literalmente le permite mover toda su rama libremente (aunque es posible que deba resolver conflictos a medida que avanza, dependiendo de dónde mueva la rama y qué contiene).

Dicho esto, una de las herramientas que puede usar en Git para determinar qué ramas o etiquetas contienen un conjunto de cambios es la --contains:

# Which branches contains commit X?
git branch --all --contains X

# Which tags contains commit X?
git tag --contains X

El aviso de recompensa en esta pregunta pregunta:

Me interesaría saber si pensar en las ramas de Git como si tuvieran un compromiso de “comienzo” definido que no sea el compromiso de raíz tiene sentido.

De alguna manera lo hace excepto:

  • la confirmación raíz es “la primera confirmación accesible de la rama HEAD “(y no olvides que puede haber múltiple root cometer con huérfano ramas, utilizadas por ejemplo en GitHub para gh-pages)
  • Prefiero considerar que el inicio de una rama es el compromiso de otro rama a partir de la cual se ha creado dicha rama (la respuesta de tobib sin el ~1), o (más simple) el ancestro común.
    (también en “¿Encontrar un punto de bifurcación con Git?”, aunque el OP mencionó que no estaba interesado en ancestros comunes):

    git merge-base A master
    

Eso significa:

  • la primera definición te da una compromiso fijo (que puede que nunca cambie excepto en caso de filter-branch)
  • la segunda definición te da una compromiso relativo (relativo a otro rama) que puede cambiar en cualquier momento (la otra rama se puede eliminar)

El segundo tiene más sentido para git, que se trata de fusionar y rebasar entre ramas.

A los supervisores a veces les gusta saber cuándo se ha iniciado una rama (generalmente marca el inicio de una tarea) y a qué rama pertenecen algunos cambios (para obtener el propósito de algún cambio, si fue necesario para el trabajo)

Las ramas son simplemente el marcador incorrecto para eso: debido a la naturaleza transitoria de las ramas (que se pueden renombrar / mover / cambiar de base / eliminar / …), no se puede imitar un “conjunto de cambios” o una “actividad” con una rama, para representar una “tarea”.

Ese es un problema XY: el OP está solicitando un intento solución (donde comienza una rama) en lugar de la problema real (lo que podría considerarse una tarea en Git).

Para hacer eso (que representa una tarea), puede usar:

  • etiquetas: son inmutables (una vez asociados a una confirmación, ya no se supone que esa confirmación se mueva / se vuelva a basar), y cualquier confirmación entre dos etiquetas bien nombradas puede representar una actividad.
  • algunos git notes a una confirmación para memorizar en qué “elemento de trabajo” se ha creado dicha confirmación (a diferencia de las etiquetas, las notas se pueden reescribir si la confirmación se modifica o se vuelve a basar).
  • ganchos (para asociar una confirmación a algún objeto “externo” como un “elemento de trabajo”, según el mensaje de confirmación). Eso es lo que hace el puente Git-RTC – IBM Rational Team Concert – con un gancho de pre-recepción) El punto es: el inicio de una rama no siempre refleja el inicio de una tarea, sino simplemente la continuación de un historial cuál puede cambiar y cuya secuencia debe representar un conjunto lógico de cambios.

Quizás esté haciendo la pregunta incorrecta. En mi opinión, no tiene sentido preguntar dónde comienza una rama, ya que una rama determinada incluye todos los cambios realizados en cada archivo siempre (es decir, desde el compromiso inicial).

Por otro lado, preguntar dónde divergieron dos ramas es definitivamente una pregunta válida. De hecho, esto parece ser exactamente lo que quiere saber. En otras palabras, realmente no desea conocer información sobre una sola rama. En su lugar, desea obtener información sobre la comparación de dos ramas.

Un poco de investigación mostró la página de manual de gitrevisions que describe los detalles de referencia a confirmaciones específicas y rangos de confirmaciones. En particular,

Para excluir confirmaciones alcanzables de una confirmación, un prefix ^ se utiliza la notación. Por ejemplo, ^ r1 r2 significa confirmaciones alcanzables desde r2 pero excluye las alcanzables desde r1.

Esta operación de conjunto aparece tan a menudo que hay una abreviatura para ella. Cuando tiene dos confirmaciones r1 y r2 (nombradas de acuerdo con la sintaxis explicada en ESPECIFICAR REVISIONES arriba), puede solicitar confirmaciones que sean accesibles desde r2 excluyendo aquellas que son accesibles desde r1 por ^ r1 r2 y se pueden escribir como r1. .r2.

Entonces, usando el ejemplo de su pregunta, puede obtener las confirmaciones donde branch-A diverge de master con

git log master..branch-A

Te invitamos a proteger nuestro estudio mostrando un comentario o dejando una puntuación te damos la bienvenida.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *