2012-03-18 11 views
28

Tengo dos ramas git, "A" y "B", y compromete a los números 1 a 8. Mi historia se parece a estogit: mover la cabeza rama

1 -> 2 -> 3 -> 4[A] -> 5 -> 6 -> 7 -> 8[B] 

quiero cambiarlo por lo que mis miradas historia de esta manera:

1 -> 2 -> 3 -> 4 -> 5 -> 6[A] -> 7 -> 8[B] 

Es decir, quiero mover la cabeza de la rama a partir de 4 comprometerse a cometer 6.

Qué comandos utilizo para hacer esto?

Respuesta

41

puede ejecutar:

git branch -f A 6 
+1

Esto funciona en esta situación porque A realmente no contiene nada; simplemente apunta al punto de ramificación y movimos el puntero a otro lugar sin perder nada. Supongamos que A tuvo algunos compromisos? Luego tienes que hacer un 'git rebase' para llevar a cabo las confirmaciones. Eso es más general y también debería manejar este caso trivial de "rama vacía". – Kaz

+4

@Kaz, git tiene ramas ligeras, por lo que nunca "contienen" nada. Son solo una nota adhesiva en movimiento adjunta a un compromiso. Mi respuesta es para este escenario, una historia de rama lineal.Si no fuera lineal, miraría lo que el OP realmente quería y encontraría una solución. –

+0

Podría decir eso también sobre CVS. Una rama no contiene nada. Es solo una etiqueta de rama ("nota adhesiva") que denota un número de rama como 1.2.0.2. ¿Tiene CVS una ramificación liviana? :) – Kaz

13
git checkout A 
git reset --hard 6 
+6

Esto funciona, pero es el "camino difícil". La razón por la que funciona es que si está "en una rama" (en términos de git), 'git reset --hard ' mueve la rama por usted. Pero 'git branch -f ' redirige la rama en un solo paso. Hay una limitación: 'git branch -f' no te permitirá mover tu rama actual. Entonces, si ya está "en la rama A" (como se muestra en la salida de 'git branch'), debe usar este método' git reset --hard'. (O salga de la rama A, pero eso es una tontería. :-)) – torek

7

Este es un caso especial de rebase, al igual que la rama está vacía:

git checkout A 
git rebase B 

rebase es más general; que maneja este caso también:

Antes:

    A1 -> A2 -> [A] 
       /
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8[B] 

Después:

         A1' -> A2' -> [A] 
            /
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8[B] 

A1' y A2' se combinan para dar cuenta de la delta entre 4 y 8 en la rama principal.

Git rebase maneja este caso trivial sin problemas. Creé un repositorio con dos confirmaciones en master y una rama br apuntando a la primera confirmación.

$ git checkout br 
Switched to branch 'br' 
$ git rebase master 
First, rewinding head to replay your work on top of it... 
Fast-forwarded br to master. 

Poof, done. El registro ahora muestra la rama que apunta a la segunda confirmación.

También podemos lograrlo "después": [gracias a M. Flaschen para señalar esto faltaba]:

      A1'' -> A2'' -> [A] 
         /
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8[B] 

En lugar de cambio de base a la rama B, que sería el nombre de la específica commit 6, p.ej

git checkout A 
git rebase 6 # rather than rebase B 

Cuando no hay A1 y A2 se compromete, esto se reduce a la pregunta original: moviendo el [A] puntero de 4 a 6.

+0

El caso anterior no coincide con la pregunta. En la pregunta, no hay confirmaciones solo en A. –

+0

El caso anterior es una generalización de la pregunta. A1 y A2 no existen. Una lista vacía es una lista. – Kaz

+1

Su caso posterior tampoco coincide. [A] apunta a 8, en lugar de 6. Además, no estoy seguro de que esta generalización ayude a responder la pregunta original. –