¿Cómo copiar confirmaciones de una rama a otra?
Tengo dos ramas de mi maestro:
- v2.1 : (versión 2) He estado trabajando durante varios meses.
- wss : que creé ayer para agregar una característica específica a mi maestro (en producción)
¿Hay alguna manera de copiar las confirmaciones de ayer de wss a v2.1?
Usar
git cherry-pick <commit>
para aplicar <commit>
a su sucursal actual .
Yo mismo probablemente verificaría las confirmaciones que selecciono gitk
y las seleccionaría haciendo clic derecho en la entrada de confirmación allí.
Si desea ser más automático (con todos sus peligros) y asumir que todas las confirmaciones desde ayer sucedieron en wss, puede generar la lista de confirmaciones usando git log
(con --pretty
lo sugerido por Jefromi)
git log --reverse --since=yesterday --pretty=%H
entonces todo junto suponiendo que usesbash
for commit in $(git log --reverse --since=yesterday --pretty=%H);
do
git cherry-pick $commit
done
Si algo sale mal aquí (hay mucho potencial), está en problemas ya que esto funciona en el pago en vivo, así que haga selecciones manuales o use rebase como lo sugiere Jefromi.
Realmente deberías tener un flujo de trabajo que te permita hacer todo esto fusionando:
- x - x - x (v2) - x - x - x (v2.1)
\
x - x - x (wss)
Entonces todo lo que tienes que hacer es git checkout v2.1
y git merge wss
. Si por alguna razón realmente no puedes hacer esto y no puedes usar git rebase para mover tu rama wss al lugar correcto, el comando para tomar una única confirmación de algún lugar 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 en que rebase podría salvarlo:
Si tu historial se ve así:
- x - x - x (v2) - x - x - x (v2.1)
\
x - x - x (v2-only) - x - x - x (wss)
Podrías usar git rebase --onto v2 v2-only wss
para mover wss directamente a v2:
- x - x - x (v2) - x - x - x (v2.1)
|\
| x - x - x (v2-only)
\
x - x - x (wss)
¡Entonces puedes fusionarte! Si realmente, realmente, realmente no puedes llegar al punto en el que puedas fusionar, aún puedes usar rebase para hacer varias selecciones a la vez de manera efectiva:
# 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 algo de trabajo adicional para hacer esto es que se crean confirmaciones duplicadas en su repositorio. Esto no es realmente algo bueno: el objetivo de una ramificación y fusión sencilla es poder hacer todo haciendo las confirmaciones en un solo lugar y fusionándolas donde sea necesario. Las confirmaciones duplicadas significan la intención de no fusionar nunca esas dos ramas (si decides que quieres hacerlo más tarde, tendrás conflictos).
git cherry-pick
: Aplicar los cambios introducidos por algunas confirmaciones existentes.
Supongamos que tenemos la rama A con confirmaciones (X, Y, Z). Necesitamos agregar estas confirmaciones a la rama B. Vamos a utilizar las cherry-pick
operaciones.
Cuando usamos cherry-pick
, debemos agregar confirmaciones en la rama B en el mismo orden cronológico en que aparecen las confirmaciones en la rama A.
cherry-pick admite una variedad de confirmaciones, pero si tiene confirmaciones de combinación en ese rango, se vuelve realmente complicado
git checkout B
git cherry-pick SHA-COMMIT-X
git cherry-pick SHA-COMMIT-Y
git cherry-pick SHA-COMMIT-Z
Ejemplo de flujo de trabajo:
Podemos usar cherry-pick
con opciones.
-e o --edit : con esta opción, git cherry-pick le permitirá editar el mensaje de confirmación antes de realizar la confirmación.
-n o --no-commit : normalmente el comando crea automáticamente una secuencia de confirmaciones. Este indicador aplica los cambios necesarios para seleccionar cada confirmación con nombre en su árbol de trabajo y el índice, sin realizar ninguna confirmación. Además, cuando se utiliza esta opción, su índice no tiene que coincidir con la confirmación HEAD. La selección se realiza en función del estado inicial de su índice.
Aquí un artículo interesante sobre git cherry-pick: puede que no sea lo que piensas sobre cherry-pick
.
Supongamos que he confirmado cambios en la rama maestra. Obtendré la identificación de confirmación ( xyz
) de la confirmación ahora. Luego tengo que ir a la rama para la que necesito enviar mis confirmaciones.
ID de confirmación únicaxyz
git checkout branch-name
git cherry-pick xyz
git push origin branch-name
Múltiples ID de confirmaciónxyz
abc
qwe
git checkout branch-name
git cherry-pick xyz abc qwe
git push origin branch-name
Las respuestas ya mencionadas cubren la mayoría de las cosas, pero una cosa que parece faltar es la --no-commit
característica de cherry-pick
ing.
Supongamos que tiene más de una confirmación en la rama de funciones y desea "fusionarlas" todas en una sola confirmación y colocarlas en su rama principal. En ese caso lo que debes hacer es:
git checkout <branch-on-which-to-add-features>
git cherry-pick --no-commit <commit-hash>
git cherry-pick --no-commit <commit-hash>
.
.
.
Y finalmente, una vez que haya cherry-pick
completado todas las funciones requeridas, puede realizar una confirmación final:
git commit -m "Some message for the merge commit"
Idealmente, como mencionó @Cascabel , deberías usar merge
o rebase
. Pero si cree que no hay otra opción, puede salirse con la suya usando cherry-pick
ing.