git cherry-pick dice "3 38c74d es una combinación pero no se dio la opción-m"


He hecho algunos cambios en mi rama master y quiero traerlos de arriba. sin embargo, cuando selecciono las siguientes confirmaciones, me quedo atascado 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 y es cherry-pick lo correcto para usar aquí? La rama master incluye cambios en los archivos que han sido modificados en la rama upstream, así que estoy seguro de que habrá algunos conflictos de fusión, pero esos no son tan malos para enderezar. Sé qué cambios son necesarios donde.

Estas son las confirmaciones que quiero traer a upstream.

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 ...
Author: wufoo, 2012-02-10

4 answers

La forma en que funciona un cherry-pick es tomando el diff 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 aplicándolo a su rama actual.

Entonces, si un commit tiene dos o más padres, también representa dos o más diferencias - ¿cuál debería aplicarse?

Estás tratando de elegir a la cereza fd9f578, que fue una fusión con dos padres. Por lo tanto, debe decirle al comando cherry-pick cuál debe compararse con el diff se calculará utilizando la opción -m. Por ejemplo, git cherry-pick -m 1 fd9f578 para usar el padre 1 como base.

No puedo decir con seguridad para su situación particular, pero usar git merge en lugar de git cherry-pick es generalmente recomendable. Cuando seleccionas un commit de fusión, colapsa todos los cambios realizados en el padre que no especificaste -m en ese un commit. Pierdes toda su historia, y juntas todas sus diferencias. Tú decides.

 403
Author: Borealid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-20 20:05:18

La respuesta de@Borealid es correcta, pero supongamos que no le importa preservar el historial exacto de fusión de una rama y solo desea seleccionar una versión linealizada de la misma. Aquí hay una manera fácil y segura de hacer eso:

Estado inicial: estás en la rama X, y quieres seleccionar las confirmaciones Y..Z.

  1. git checkout -b tempZ Z
  2. git rebase Y
  3. git checkout -b newX X
  4. git cherry-pick Y..tempZ
  5. (optativo) git branch -D tempZ

, Lo que esto hace es crear una rama tempZ basado en Z, pero con el historial de Y en adelante linealizado, y luego elija eso en una copia de X llamada newX. (Es más seguro hacer esto en una rama nueva en lugar de mutar X. Por supuesto, puede haber conflictos en el paso 4, que tendrá que resolver de la manera habitual (cherry-pick funciona muy parecido a rebase en ese sentido). Finalmente elimina la rama temporal tempZ.

Si el paso 2 da el mensaje "Current branch tempZ is up to date", entonces Y..Z ya estaba 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 rama Z, porque no depende de ninguna manera de la relación entre X y Y; puede haber confirmaciones entre el ancestro común y Y que no querías.)

 18
Author: Daira Hopwood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-25 00:26:02

He aquí 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 seleccionar una fusión, lo más simple es seleccionar la(s) confirmación (es) que realmente deseas de cada rama en la fusión.

Dado que ya has fusionado, es probable que todas tus confirmaciones deseadas estén en tu lista. Cherry-elígelos directamente y no es necesario meterse con la confirmación de fusión.

Explicación

La forma en que funciona un cherry-pick 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 se produce debido a la incertidumbre sobre qué diff debe aplicar.

Alternativas

Si determinas que necesitas incluir la combinación vs seleccionar las confirmaciones relacionadas, tienes dos opciones:

  1. (Más complicado y oscuro; también descarta el historial) puede indicar qué padre debe aplicar.

    • Utilice la opción -m para hacerlo. Por ejemplo, git cherry-pick -m 1 fd9f578 usará el primer padre listado en la fusión como base.

    • También tenga en cuenta que cuando elige una confirmación de fusión, se colapsa todos los cambios realizados en el padre que no especificó a -m en ese un commit. Pierdes toda su historia, y juntas todas sus diferencias. Tú decides.

  2. (Más simple y más familiar; conserva la historia) puede usar git merge en lugar de git cherry-pick.

    • Como es habitual con git merge, intentará aplicar todas las confirmaciones que existen en la rama que está fusionando, y listarlas individualmente en su registro de git.
 3
Author: Kay V,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-23 14:02:37

Simplificación del método @Daira Hopwood buena para elegir un solo commit. No necesita sucursales temporales.

En el caso del autor:

  • Z es la confirmación deseada (fd9f578)
  • Y es commit antes de él
  • X rama de trabajo actual

Entonces haz:

git checkout Z   # move HEAD to wanted commit
git reset Y      # have Z as changes in working tree
git stash        # save Z in stash
git checkout X   # return to working branch
git stash pop    # apply Z to current branch
git commit -a    # do commit
 0
Author: ephemerr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-23 06:49:18