2010-03-19 162 views
455

Tengo dos ramas de mi maestro:¿Cómo copiar los commits de una rama a otra?

  • v2.1: (versión 2) He estado trabajando durante varios meses
  • WSS: que creé ayer añadir una característica específica de mi maestro (en producción)

¿Hay alguna manera de copiar las confirmaciones de ayer de wss a v2.1?

+0

Para simplemente copiar commits (o un rango de commits) de una rama a otra, esta respuesta me ayudó mucho: http://stackoverflow.com/questions/1994463/how-to-cherry-pick-a-range-of -commits-and-merge-into-another-branch/1994491 # 1994491 – caramba

+0

[Confirmaciones específicas de Cherry-Picking desde otra sucursal] (https://ariejan.net/2010/06/10/cherry-picking-specific-commits- from-another-branch /) – KyleMit

Respuesta

391

realmente debería tener un flujo de trabajo que le permite hacer todo esto mediante la fusión:

- x - x - x (v2) - x - x - x (v2.1) 
      \ 
      x - x - x (wss) 

Así que todo lo que tiene que hacer es git checkout v2.1 y git merge wss. Si por alguna razón realmente no puede hacer esto, y no puede usar git rebase para mover su rama wss al lugar correcto, el comando para tomar una confirmación simple de alguna parte y aplicarla en otro lugar es git cherry-pick. Simplemente revisa la rama en la que deseas aplicarlo y ejecuta git cherry-pick <SHA of commit to cherry-pick>.

Algunas de las formas rebase podría ahorrar:

Si su historia es el siguiente:

- x - x - x (v2) - x - x - x (v2.1) 
      \ 
      x - x - x (v2-only) - x - x - x (wss) 

Usted podría utilizar git rebase --onto v2 v2-only wss para mover WSS directamente sobre v2:

- x - x - x (v2) - x - x - x (v2.1) 
      |\ 
      | x - x - x (v2-only) 
      \ 
      x - x - x (wss) 

Entonces ¡puedes unirte! Si realmente, realmente, realmente puede no llegar al punto donde se puede fusionar, puede seguir utilizando rebase hacer efectiva varios cereza-picks a la vez:

# wss-starting-point is the SHA1/branch immediately before the first commit to rebase 
git branch wss-to-rebase wss 
git rebase --onto v2.1 wss-starting-point wss-to-rebase 
git checkout v2.1 
git merge wss-to-rebase 

Nota: la razón por la que se necesita un poco de trabajo adicional para hacer esto es que está creando commits duplicados en su repositorio. Esto no es realmente una buena cosa: el objetivo de una fácil bifurcación y fusión es poder hacer todo haciendo un commit (s) en un lugar y fusionándolos donde se necesiten. Los commits duplicados significan la intención de nunca fusionar esas dos ramas (si decides que quieres más adelante, obtendrás conflictos).

+1

No podría estar más de acuerdo con esta respuesta. +1. Ver también mi respuesta anterior para ilustrar las consecuencias de la selección de cerezas: http://stackoverflow.com/questions/881092/how-to-merge-a-specific-commit-in-git/881112#881112 – VonC

+9

Excelente respuesta sobre cómo para hacer esto de la manera * adecuada *! También me gustaría poder votar dos veces por el esfuerzo de crear diagramas ASCII. – gotgenes

+0

@VonC: Gracias por el apoyo y la información adicional sobre por qué no hacer una selección: sé que escatimé un poco allí. @gotgenes: ¡Gracias! Creo que vale la pena el esfuerzo, solo mire la página de git-rebase. No hay mejor manera de explicarlo. – Cascabel

12

Puede create a patch desde las confirmaciones que desea copiar y apply the patch hasta la sucursal de destino.

+12

Incluso si, por alguna razón, realmente desea utilizar parches en lugar de cherry-pick (s)/rebase, la forma directa de hacerlo es con 'git format-patch 'y' git am * .patch'. – Cascabel

559

Uso

git cherry-pick <commit> 

aplicar <commit> a su rama actual.

Yo mismo probablemente verifique las confirmaciones que selecciono en gitk y las selecciono con el botón derecho en la entrada de confirmación allí.


Si quieres ir más automático (con todos sus peligros) y suponiendo que todos los envíos desde ayer ocurrió el WSS que podría generar la lista de confirmaciones utilizando git log con (--pretty sugerido por Jefromi)

git log --reverse --since=yesterday --pretty=%H 

así todo junto suponiendo que el uso bash

for commit in $(git log --reverse --since=yesterday --pretty=%H); 
do 
    git cherry-pick $commit 
done 

Si algo va mal aquí (hay un montón de potencial) usted está en problemas ya que esto funciona en el proceso de pago en vivo, por lo tanto, haga selecciones de cerezas manuales o use rebase como lo sugirió Jefromi.

+1

La versión más corta que está buscando es 'git log --since = yesterday --reverse --pretty =% H'. – Cascabel

+9

@Jefromi Gracias, eso es una bandera 'bonita' útil. Respuesta actualizada –

+0

Todos los marcadores de posición para la opción --pretty se encuentran en la página de manual de git-log. Puede obtener cualquier formato que desee, particularmente útil para obtener los campos que desea para un script en una forma fácil de analizar. – Cascabel

9

O si eres un poco menos del lado del evangelista, puedes hacer un poco de la manera fea que estoy usando. En deploy_template hay confirmaciones quiero copiar en mi maestro como rama desplegar

git branch deploy deploy_template 
git checkout deploy 
git rebase master 

Esto creará nueva rama de despliegue (utilizo -f para sobrescribir existente desplegar rama) en deploy_template, entonces rebase esta nueva rama en maestro, dejando deploy_template intacto.

Cuestiones relacionadas