Cómo crear la rama a partir de un compromiso específico en una rama diferente

102

Hice varias confirmaciones en la rama maestra y luego las fusioné con la rama dev.

Quiero crear una rama a partir de una confirmación específica en la rama dev, que se comprometió por primera vez en la rama maestra.

Usé los comandos:

git checkout dev
git branch  <branch name> <commit id>

Sin embargo, esto crea la rama de la rama maestra, no la rama de desarrollo que esperaba. La identificación de confirmación es la misma en la rama maestra y la rama dev. Entonces, ¿cómo puedo distinguir el mismo ID de confirmación en diferentes ramas?

PD: hice un ejemplo en github aquí https://github.com/RolandXu/test_for_branch

Usé los comandos:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8

Lo que espero es que la rama de prueba contenga aa.txt bb.txt cc.txt. Sin embargo, la rama de prueba solo contiene aa.txt y cc.txt. Lo más probable es que haya creado la rama desde la rama principal.

RolandXu
fuente

Respuestas:

145

Si está utilizando esta forma del branchcomando (con punto de inicio), no importa dónde se HEADencuentre.

Qué estás haciendo:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8
  • Primero, estableces tu HEADen la rama dev,

  • En segundo lugar, comienzas una nueva rama al confirmar 07aeec98. No hay bb.txt en esta confirmación (de acuerdo con su repositorio de github).

Si desea iniciar una nueva sucursal en la ubicación que acaba de retirar, puede ejecutar una sucursal sin un punto de inicio:

git branch test

o como otros han respondido, bifurque y pague allí en una sola operación:

git checkout -b test

Creo que puede confundirte el hecho de que 07aeec98es parte de la rama dev. Es cierto que este compromiso es un antepasado de dev, sus cambios son necesarios para alcanzar el último compromiso en dev. Sin embargo, hay otras confirmaciones que se necesitan para alcanzar las últimas dev, y no están necesariamente en la historia de 07aeec98.

8480e8ae(donde agregó bb.txt) no está, por ejemplo, en el historial de 07aeec98. Si se bifurca desde 07aeec98, no obtendrá los cambios introducidos por 8480e8ae.

En otras palabras: si fusiona la rama A y la rama B en la rama C, luego crea una nueva rama en una confirmación de A, no obtendrá los cambios introducidos en B.

Lo mismo aquí, tenías dos ramas paralelas master y dev, que fusionaste en dev. La ramificación de una confirmación de master (anterior a la fusión) no le proporcionará los cambios de dev.


Si desea integrar permanentemente los nuevos cambios del maestro en sus ramas de funciones, debe fusionarlos mastery continuar. Sin embargo, esto creará confirmaciones de fusión en sus ramas de características.

Si aún no ha publicado sus ramas de características, también se puede reajustar ellos en el maestro actualización: git rebase master featureA. Esté preparado para resolver posibles conflictos.

Si desea un flujo de trabajo en el que pueda trabajar en ramas de funciones sin compromisos de fusión y aún así integrarse con cambios más nuevos en el maestro, le recomiendo lo siguiente:

  • base cada nueva rama de características en una confirmación de maestro
  • crear una devrama en un compromiso de maestro
  • cuando necesite ver cómo su rama de características se integra con los nuevos cambios en el maestro, combine tanto el maestro como la rama de características en dev.

No se comprometa devdirectamente, utilícelo solo para fusionar otras ramas.

Por ejemplo, si está trabajando en la función A y B:

a---b---c---d---e---f---g -master
    \       \
     \       \-x -featureB
      \
       \-j---k -featureA

Fusionar ramas en una devrama para comprobar si funcionan bien con el nuevo maestro:

a---b---c---d---e---f---g -master
    \       \            \
     \       \            \--x'---k' -dev
      \       \             /    /   
       \       \-x----------    /    -featureB
        \                      /
         \-j---k--------------- -featureA

Puede seguir trabajando en sus ramas de funciones y seguir incorporando nuevos cambios de las ramas principal y de funciones con devregularidad.

a---b---c---d---e---f---g---h---i----- -master
    \       \            \            \
     \       \            \--x'---k'---i'---l' -dev
      \       \             /    /         /
       \       \-x----------    /         /  -featureB
        \                      /         /  
         \-j---k-----------------l------ -featureA

Cuando sea el momento de integrar las nuevas funciones, combine las ramas de funciones ( dev¡ no !) En master.

Gauthier
fuente
Gracias. Responde a mi pregunta. Me equivoco al comprender el modo de rama de git. Y tienes alguna sugerencia para mi problema. Tengo la rama maestra que tiene muchas confirmaciones oportunas de otras (sincronizar con forzosamente). Tengo una rama de desarrollo que hago trabajo personal. Quiero una rama que contenga todas las confirmaciones de la rama maestra y la rama de desarrollo, luego puedo crear fácilmente una rama basada en esta rama y luego comenzar a trabajar específicamente.
RolandXu
No pude responder en un comentario, así que actualizo mi respuesta con flujos de trabajo sugeridos.
Gauthier
¡Oye, gracias por la brillante y completa respuesta! Solo curiosidad: al final, ¿por qué debería uno merge the feature branches (not dev!) into master?
cassi.lup
No hay un nuevo desarrollo real en la devrama. Debe mantener las características específicas de sus sucursales. devcontiene solo merge commits. Tiene más sentido fusionar todas las funciones nuevas directamente master, que fusionar las funciones y luego fusionar el resultado en master.
Gauthier
@Gauthier No respondió la pregunta de por qué. Para mí suena como fusionar un devcon solo características A By Cfusionarlo en masteres idéntico a fusionar individualmente A By Cen master. Si no, eso desafía mi comprensión de cómo funciona git y ¡tendría mucha curiosidad por saber por qué!
Steven Lu
53

Tiene los argumentos en el orden incorrecto:

git branch <branch-name> <commit>

y para eso, no importa qué rama esté desprotegida; hará lo que dices. (Si omite el argumento de confirmación, de forma predeterminada se crea una rama en el mismo lugar que la actual).

Si desea ver la nueva rama a medida que la crea:

git checkout -b <branch> <commit>

con el mismo comportamiento si omite el argumento de confirmación.

Cascabel
fuente
22

Puede hacer esto localmente como todos mencionaron usando

git checkout -b <branch-name> <sha1-of-commit>

Alternativamente, puede hacer esto en github, siga los pasos:

1- En el repositorio, haga clic en el Commits.

2- en la confirmación desde la que desea ramificarse, haga clic en <>para navegar por el repositorio en este punto del historial.

comete historia

3- Haz clic en tree: xxxxxxen la parte superior izquierda. Simplemente escriba un nuevo nombre de rama allí, haga clic Create branch xxxcomo se muestra a continuación.

crear nueva rama

Ahora puede obtener los cambios de esa rama localmente y continuar desde allí.

Muhammad Soliman
fuente
Esto es lo que necesitaba .. Cómo hacerlo en el sitio web
eharo2
Yo nunca lo supe. Eso es todo. Lo de la GUI es genial y quería estar lejos de CLI.
Rohit Gupta
10

Tratar

git checkout <commit hash>
git checkout -b new_branch

La confirmación solo debe existir una vez en su árbol, no en dos ramas separadas.

Esto le permite verificar esa confirmación específica y nombrarla como desee.

ZMorek
fuente
hola, pruebo git log dev y git log master, encontré que el ID de hash de confirmación es el mismo para la confirmación que
fusiono con la
podría ser útil usar algo como gitkvisualizar su registro
ZMorek
Recientemente agregué un ejemplo en github. Y Gauthier ya respondió a mi pregunta de que no entiendo bien el modo de rama de git. Gracias :)
RolandXu
Creo que esta es una respuesta aguda. Gracias
virusss8
9

Tu tienes que hacer:

git branch <branch_name> <commit>

(estabas intercambiando el nombre de la rama y confirmando)

O puedes hacer:

git checkout -b <branch_name> <commit>

Si en lugar de usar el nombre de la rama, obtendrá una rama de la punta de la rama.

manojlds
fuente
Eso no es lo que HEADsignifica. En su lugar, podría decir "la punta de la rama" o "la confirmación a la que apunta la rama".
Cascabel
@Jefromi - Para ser puristas, podemos decir solo la rama, ya que la rama en sí misma apunta a, bueno, la punta de la rama.
manojlds