2010-04-29 10 views
40

Actualmente estoy trabajando en una rama y quiere algunas compromete a fundirse en otras ramas:Reordenamiento de confirmaciones

a-b-c-d-e-f-g (branchA) 
/
--o-x-x-x-x-x-x-x-x-x-x (master) 
    \ 
    x-x-x-x-x (branchB) 

(letras indican las confirmaciones, y la "x" se compromete irrelevantes.)

Sin embargo, noté que sería una buena idea agrupar algunos commits. Quiero "concatenar" cometer a, d, eyg en un parche y comprometerlo a dominar. Los compromisos b y f deberían ir como uno se compromete a branchB. ¿Hay una buena manera de 'git'-ish para lograrlo?

+4

las dos respuestas ya dadas mención el comando correcto, pero creo que con una tarea tan básico como éste, es vale la pena tener instrucciones reales aquí en StackOverflow, así que he publicado algunas. (Me sorprende que no pueda encontrar una buena pregunta previa para vincular). – Cascabel

Respuesta

0

git rebase es lo que quiere. Echa un vistazo a la opción interactiva.

+0

Agregue detalles relevantes de su enlace para proporcionar una respuesta completa e independiente. SO frunce el ceño ante "respuestas de solo enlace". – SherylHohman

69

El comando que está buscando es git rebase, específicamente la opción -i/--interactive.

Voy a suponer que quiere dejar commit c en la rama A, y que realmente quiere decir que quiere mover las otras confirmaciones a las otras ramas, en lugar de fusionarse, ya que las fusiones son sencillas. Vamos a empezar por la manipulación de la rama A.

git rebase -i <SHA1 of commit a>^ branchA 

El ^ significa cometer el anterior, por lo que esta orden le dice al rebasar la rama A usando el commit antes "a" como la base. Git te presentará una lista de confirmaciones en este rango. Reordenarlos y decirle a Git para aplastar los apropiados:

pick c ... 
pick a ... 
squash d ... 
squash e ... 
squash g ... 
pick b 
squash f 

Ahora la historia debería tener este aspecto:

c - [a+d+e+g] - [b+f] (branchA) 
/
--o-x-x-x-x-x-x-x-x-x-x (master) 

Ahora, vamos a agarrar el recién aplastado cometer B + F para branchB.

git checkout branchB 
git cherry-pick branchA # cherry-pick one commit, the tip of branchA 

Y lo mismo para a + d + e + g para el amo:

git checkout master 
git cherry-pick branchA^ 

Por último, la actualización branchA para que apunte a c:

git branch -f branchA branchA^^ 

Ahora deberíamos tener:

c (branch A) - [a+d+e+g] - [b+f] (dangling commits) 
/
--o-x-x-x-x-x-x-x-x-x-x-[a+d+e+g] (master) 
    \ 
    x-x-x-x-x-[b+f] (branchB) 

Ten en cuenta que si tienes múltiples compromisos yo u quería para moverse entre las ramas, se puede usar rebase de nuevo (no interactiva):

# create a temporary branch 
git branch fromAtoB branchA 
# move branchA back two commits 
git branch -f branchA branchA~2 
# rebase those two commits onto branchB 
git rebase --onto branchB branchA fromAtoB 
# merge (fast-forward) these into branchB 
git checkout branchB 
git merge fromAtoB 
# clean up 
git branch -d fromAtoB 

Por último, una advertencia: Es muy posible reordenar compromete de tal manera que algunos ya no se aplican limpiamente. Esto podría deberse a que eligió un pedido incorrecto (poniendo un parche antes de la confirmación introduciendo la función que parchó); en ese caso, querrá abortar la rebase (git rebase --abort).De lo contrario, deberá corregir los conflictos de forma inteligente (como lo hace con los conflictos de combinación), agregar las correcciones y luego ejecutar git rebase --continue para continuar. Estas instrucciones también son provistas por el mensaje de error impreso cuando ocurre el conflicto.

+0

no es el diagrama después de que la rama 'git -f branchA branchA ^^' ¿está equivocada? A saber, no debería branchA apuntar a c en este punto, de modo que la primera línea del diagrama es 'c (branchA)' y no 'c - [a + d + e + g] - [b + f] (branchA) '? – ntc2

+0

@enoksrd: Sí, hay un error, pero tu edición tenía errores. Lo arreglaré cuando tenga oportunidad aquí. – Cascabel

Cuestiones relacionadas