¿Cómo elegir un rango de commits y fusionarlos en otra rama?
Tengo el siguiente diseño de repositorio:
- rama maestra (producción)
- integración
- de trabajo
Lo que quiero conseguir es seleccionar un rango de commits de la rama de trabajo y fusionarlo con la rama de integración. Soy bastante nuevo en git y no puedo averiguar cómo hacer esto exactamente (la selección de rangos de commits en una operación, no la fusión) sin desordenar el repositorio. ¿Algún consejo o idea sobre esto? Gracias.
592
3
Cuando se trata de un rango de commits, el cherry-picking
es*no es práctico.Como se menciona a continuación por Keith Kim, Git 1.7.2+ introdujo la capacidad de hacer cherry-pick de un rango de commits (pero todavía hay que ser consciente de la consecuencia de hacer cherry-pick para futuras fusiones)
damian comentarios y nos advierte:
Si quieres escoger el rango
B
hastaD
(inclusive) seríaB^..D
.Ver "¿Git crear rama a partir de un rango de commits anteriores?" como ilustración.
Como menciona Jubobs en los comentarios:
Nota: a partir de Git 2.9.x/2.10 (Q3 2016), se puede hacer cherry-pick de un rango de commit directamente en una rama huérfana (cabeza vacía): ver "Cómo hacer que una rama existente sea huérfana en git".
Respuesta original (enero de 2010)
Una
rebase --onto
sería mejor, donde se reproduce el rango de commit dado sobre su rama de integración, como Charles Bailey describió aquí.(también, busca "Así es como se trasplanta una rama temática basada en una rama a otra" en la página man de git rebase, para ver un ejemplo práctico de
git rebase --onto
)Si tu rama actual es la de integración:
`lang-all: lang-sh -->
Eso reproducirá todo lo que hay entre ellos:
first_SHA-1_of_working_branch_range
(de ahí el~1
): la primera confirmación que quieres reproducir" (que apunta a la última confirmación que desea reproducir, de la rama
working`)hasta "Tmp
" (que apunta a donde apuntaba antes
integración`)Si hay algún conflicto cuando se reproduce uno de esos commits
" (y volver a poner la rama
integraciónen la rama
tmp`)Después de ese
rebase --onto
,integration
volverá a estar en el último commit de la rama de integración (es decir "tmp
" rama + todos los commits reproducidos)Con cherry-picking o
rebase --onto
, no olvide que tiene consecuencias en las fusiones posteriores, como se describe aquí.Una solución pura de
cherry-pick
" es discutida aquí, e implicaría algo como:Pero de todos modos, cuando necesites "repetir" un rango de confirmaciones, la palabra "repetir" debería empujarte a usar la función "rebase" de Git.
¿Estás seguro de que no quieres fusionar las ramas? Si la rama de trabajo tiene algunos commits recientes que no quieres, puedes simplemente crear una nueva rama con un HEAD en el punto que quieras.
Ahora bien, si realmente quieres seleccionar un rango de commits, por la razón que sea, una forma elegante de hacerlo es simplemente tirar de un conjunto de parches y aplicarlo a tu nueva rama de integración:
Esto es esencialmente lo que git-rebase hace de todos modos, pero sin la necesidad de jugar. Puedes añadir
--3way
agit-am
si necesitas fusionar. Asegúrate de que no hay otros archivos *.patch ya en el directorio donde haces esto, si sigues las instrucciones al pie de la letra...He envuelto el código de VonC's en un corto script bash,
git-multi-cherry-pick
, para facilitar su ejecución:Actualmente estoy usando esto mientras reconstruyo la historia de un proyecto que tenía código de terceros y personalizaciones mezcladas en el mismo trunk de svn. Ahora estoy separando el código de terceros, los módulos de terceros y las personalizaciones en sus propias ramas git para una mejor comprensión de las personalizaciones en el futuro. El
git-cherry-pick
es útil en esta situación ya que tengo dos árboles en el mismo repositorio, pero sin un ancestro compartido.