Hice algunos cambios en mi rama maestra y quiero llevarlos hacia arriba. cuando selecciono las siguientes confirmaciones, sin embargo, me atoro en fd9f578 donde git dice:
$ git cherry-pick fd9f578
fatal: Commit fd9f57850f6b94b7906e5bbe51a0d75bf638c74d is a merge but no -m option was given.
¿Qué está tratando de decirme git? ¿Es la elección correcta para usar aquí? La rama maestra incluye cambios en los archivos que se han modificado en la rama ascendente, por lo que estoy seguro de que habrá algunos conflictos de fusión, pero esos no son demasiado malos para solucionarlos. Sé qué cambios son necesarios y dónde.
Estas son las confirmaciones que quiero presentar.
e7d4cff added some comments...
23e6d2a moved static strings...
44cc65a incorporated test ...
40b83d5 whoops delete whitspace...
24f8a50 implemented global.c...
43651c3 cleaned up ...
068b2fe cleaned up version.c ...
fd9f578 Merge branch 'master' of ssh://extgit/git/sessions_common
4172caa cleaned up comments in sessions.c ...
fuente
git rebase
: es como una fusión, pero en lugar de integrar dos ramas, trasplanta una para sentarse encima de la otra.git show
y similares).git reset --hard HEAD@{1}
para recuperar su confirmación faltante.git reset
no se limita a moverse "hacia atrás" en la historia.git checkout -b mybranch HEAD@{1}
También funcionaría.git merge
puede tener consecuencias no deseadas. Ese comando agregará todas las otras confirmaciones (anteriores) que existen en la rama principal. Por lo general, las personas optan por elegir porque no quieren los otros compromisos. ¡Asegúrese de verificar que solo está implementando los cambios que desea!-m
significa el número padre.Del git doc:
Por ejemplo, si su árbol de confirmación es el siguiente:
entonces
git cherry-pick E
producirá el problema que enfrentó.git cherry-pick E -m 1
significa usarD-E
, mientras quegit cherry-pick E -m 2
significa usarB-C-E
.fuente
La respuesta de @ Borealid es correcta, pero suponga que no le importa preservar el historial exacto de fusión de una rama y solo quiere elegir una versión linealizada. Aquí hay una manera fácil y segura de hacerlo:
Estado de inicio: está en la sucursal
X
y desea seleccionar los commitsY..Z
.git checkout -b tempZ Z
git rebase Y
git checkout -b newX X
git cherry-pick Y..tempZ
git branch -D tempZ
Lo que esto hace es crear una rama
tempZ
basada enZ
, pero con el historialY
linealizado en adelante, y luego seleccionarlo en una copia deX
llamadonewX
. (Es más seguro hacer esto en una nueva rama en lugar de mutarX
). Por supuesto, puede haber conflictos en el paso 4, que tendrá que resolver de la manera habitual (cherry-pick
funciona de manera muy similarrebase
a ese respecto). Finalmente borra lo temporaltempZ
rama .Si el paso 2 muestra el mensaje "La rama actual tempZ está actualizada", entonces
Y..Z
ya era lineal, así que simplemente ignore ese mensaje y continúe con los pasos 3 en adelante.Luego revise
newX
y vea si eso hizo lo que quería.(Nota: esto no es lo mismo que un simple
git rebase X
cuando está en la ramaZ
, porque no depende de ninguna manera de la relación entreX
yY
; puede haber compromisos entre el antepasado común y elY
que no desea).fuente
git rebase Y
diceCurrent branch tempZ is up to date
Y..Z
ya era lineal. Entonces puede ignorar ese mensaje y continuar con los pasos 3 y 4.Simplificar. Cherry-recoger los commits. No escojas la combinación.
Aquí hay una reescritura de la respuesta aceptada que idealmente aclara las ventajas / riesgos de los posibles enfoques:
Estás tratando de elegir fd9f578, que fue una fusión con dos padres.
En lugar de elegir una fusión, lo más simple es elegir las confirmaciones que realmente desea de cada rama de la fusión.
Como ya se ha fusionado, es probable que todas sus confirmaciones deseadas estén en su lista. Escoge cereza directamente y no necesitas meterte con la confirmación de fusión.
explicación
La forma en que funciona una selección de cereza es tomando la diferencia que representa un conjunto de cambios (la diferencia entre el árbol de trabajo en ese punto y el árbol de trabajo de su padre) y aplicando el conjunto de cambios a su rama actual.
Si un commit tiene dos o más padres, como es el caso de una fusión, ese commit también representa dos o más diferencias. El error ocurre debido a la incertidumbre sobre la cual debería aplicarse diff.
alternativas
Si determina que necesita incluir la combinación vs selección de cereza de las confirmaciones relacionadas, tiene dos opciones:
(Más complicado y oscuro; también descarta el historial) puede indicar qué padre debe aplicar.
Use la
-m
opción para hacerlo. Por ejemplo,git cherry-pick -m 1 fd9f578
usará el primer padre que aparece en la fusión como base.También tenga en cuenta que cuando selecciona una confirmación de fusión, contrae todos los cambios realizados en el elemento primario que no especificó
-m
en esa confirmación . Pierdes toda su historia y engullen todas sus diferencias. Tu llamada.(Más simple y más familiar; conserva el historial) que puede usar en
git merge
lugar degit cherry-pick
.git merge
, intentará aplicar todas las confirmaciones que existen en la rama que está fusionando, y enumerarlas individualmente en su registro de git.fuente
Simplificación del método @Daira Hopwood bueno para elegir una sola confirmación. No necesita ramas temporales.
En el caso del autor:
entonces hazlo:
fuente