Git rebase y twigs de niños

Tengo la siguiente situación, en mi proyecto

Master M1----M2----M3----M4----M5 \ Beta B1----B2----B3---B4 \ Feature F1---F2---F3 

Estoy desarrollando en Feature , pero se publicó una actualización realmente importante en commit M5 , y no quiero separar Feature de B3 (la Feature depende de B1 y B2 ), y Beta puede tener el cambio (no hay diferencia para Beta ).

Si hago un git rebase Master en Beta , solo movería la twig Beta , a la derecha (¿no se aplicaron cambios en la Feature )? O terminaría así (Abajo: ¿los cambios también se aplicaron en la Feature )?

 Master M1----M2----M3----M4----M5 \ Beta B1----B2----B3---B4 \ Feature F1---F2---F3 

Y, para ser así (cambios aplicados en la Feature ), ¿qué debo hacer? Ese es mi estado deseado …

Estás en lo cierto: ejecutar git rebase Master mientras está git rebase Master Beta no afectará a la Feature . (Aparte: ¿por qué las letras mayúsculas?)

El problema fundamental aquí es que git rebase "significa" copyr algunos commits . El truco está en ver qué commits se copyn, hacia dónde y qué sucede con los nombres de las twigs después. Si las confirmaciones que se copyron también son accesibles desde otra twig, los originales, antes de la copy, siguen siendo accesibles desde esa otra twig.

Recuerde que todos los nombres de las twigs son solo pointers, que apuntan a la confirmación más reciente en la twig. Todas las confirmaciones principales anteriores están en esa twig, incluso si esas confirmaciones anteriores también están en otras twigs. Entonces, "todos los compromisos Beta " incluyen inicialmente M1 a M3 .

Entonces, ¿cómo sabe la primera database de git rebase copyr solo B1 , B2 , B3 y B4 ? Creo que un elemento key es dibujar el gráfico de forma un poco diferente:

 M1----M2----M3----M4----M5 <-- Master \ B1----B2----B3---B4 <-- Beta \ F1---F2---F3 <-- Feature 

Para ver lo que se va a copyr, tome un marcador verde con la sugerencia de punta de la twig, es decir, B4 como lo señala Beta , y colorea todo verde a medida que sigue las líneas hacia la izquierda. Eso incluye commits M3 y anteriores. Luego, toma un resaltador rojo hasta el compromiso de punta de la Master (eso es M5), y el color todo se vuelve rojo mientras sigues las líneas a la izquierda. El rojo sobre-pinta el verde, por lo que M3 y anteriores no se consideran para copyr. Esto deja exactamente el set correcto de confirmaciones para copyr.

Las copys aterrizan después de que la punta se haya comprometido con el argumento. Eso es Master , entonces las copys vienen después de M5 .

Después de que Git realiza la copy, Git mueve el nombre Beta para que apunte a la copy de B4 , que llamaremos B4' . Eso deja al Bn original comprometido … excepto que B3 es alcanzable desde F1 :

  B1'---B2'---B3'--B4 <-- Beta / M1----M2----M3----M4----M5 <-- Master \ B1----B2----B3---B4 [no name] \ F1---F2---F3 <-- Feature 

Así que todo está bien para Beta , pero ahora le gustaría copyr las confirmaciones de Feature . Si tu:

 git checkout Feature git rebase Beta 

Git coloreará F3 verde, luego F2 y F1 … pero luego continuará marcando B3 a través de B1 verde también. Solo las copys y los cinco compromisos M se sobrescriben con rojo. Entonces, Git copyrá demasiados commits.

La solución es usar git rebase --onto <name> . Agregar --onto le dice a Git dónde colocar las copys: quiere que vayan después de B4' , para que pueda decir --onto Beta decir que las copys van después de Beta, es decir, B4' .

Eso en realidad no arregla nada … todavía. Pero libera el otro argumento, el que era Beta , para ser, bueno, algo más.

Lo que quieres es decirle a Git dónde empezar a marcar confirmaciones rojas. Eso es B3 , o si es más fácil, B4 . Eso marcará B3 y todas sus confirmaciones anteriores (incluso M3 y también antes) en rojo: no copie.

Puede usar la ID sin procesar de B3 , si la guarda. O puede hacer que Git busque fácilmente la punta anterior de Beta usando Beta@{1} :

 git rebase --onto Beta Beta@{1} 

Esto encuentra el ID de hash de la confirmación B4 usando el reflog para Beta .

En realidad, terminaría con algo como esto:

 Master M1----M2----M3----M4----M5 \ \ \ Beta B1----B2----B3---B4 \ \--B1'---B2'---B3'----F1---F2---F3 ^ feature 

Básicamente, su rebase para Beta volverá a aplicar las confirmaciones en Beta en la parte superior del consejo actual del maestro. Sin embargo, las confirmaciones originales seguirán existiendo y, si algo más, como otra twig, se refiere a esas confirmaciones, aún persistirán.

Necesitaría primero volver a establecer la base de Beta y luego volver a establecer la feature de base para mover todo "al lugar correcto".