Pregunta ¿Cómo puedo fusionar muchas confirmaciones, pero dejar una?


Supongamos que tengo esta rama de función "foo". Ahora quiero fusionarlo de nuevo en el maestro, pero he agregado un código de depuración que no quiero en el maestro.

El código de depuración está en su propia confirmación, así que podría usar git cherry-pick en cada commit y omite este commit. Pero eso va a ser bastante tedioso.

¿Hay alguna "selección inversa" que hace esto, o una combinación interactiva?


74
2017-10-26 13:13


origen


Respuestas:


Use rebase interactivo:

git rebase -i SHA-OF-FIRST-COMMIT-IN-BRANCH

Eso abrirá algo como esto en tu $ EDITOR:

    pick 8ac4783 folders and folders
    pick cf8b1f5 minor refactor
    pick 762b37a Lots of improvement. Folders adn shit.
    pick 3fae6e1 Be ready to tableview
    pick b174dc0 replace folder collection view w/ table view
    pick ef1b65b more finish
    pick ecc407f responder chain and whatnot
    pick 080a847 play/pause video
    pick 6719000 wip: movie fader
    pick c5f2933 presentation window fade transition

    # Rebase e6f77c8..c5f2933 onto e6f77c8
    #
    # Commands:
    #  p, pick = use commit
    #  e, edit = use commit, but stop for amending
    #  s, squash = use commit, but meld into previous commit
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    # However, if you remove everything, the rebase will be aborted.
    #

Entonces, lo que debes hacer es simplemente eliminar la línea que contiene la confirmación de depuración, escribir el archivo y cerrar el editor, y git te dirá algo como:

Successfully rebased and updated refs/heads/master.

Ahora puedes simplemente fusionarte en esa rama para dominar.

ACTUALIZACIÓN: se debe tener en cuenta que la alteración de la historia con rebase debería solamente suceder en sucursales privadas. Si esta rama ha estado expuesta al público, use git revert según lo propuesto por otro respondedor.


54
2017-10-26 13:16



A pesar de lo que otros SCMs usan para significar, en git, git revert es una selección inversa de cereza.


67
2017-10-26 13:16



Otra idea es agregar la confirmación revertida de la que tiene el código de depuración y fusionarla en su rama principal. Luego eliminamos ese compromiso extra en la rama foo.

git checkout foo
git revert COMMIT_REF_WITH_DEBUG_CODE

git checkout master
git merge foo

git checkout foo
git reset --hard HEAD~1

Asegúrate de que tu árbol de trabajo esté limpio. Primero crea la confirmación revertida. Luego, combínalo en maestro. Luego reinicie el puntero de rama de la rama foo al padre de la confirmación revertida, por lo que vuelve a estar en su estado original.

Si no te gusta usar git reset entonces puedes crear una rama temporal donde creas la confirmación revertida. Al final, eliminas la rama temporal.


7
2017-07-26 18:30



Use la base de datos interactiva para eliminar las confirmaciones que no desea.

En una nueva rama "foo-merge" creada a partir de "foo":

git rebase -i master

Una vez que esté en modo de edición de compromiso, elimine las líneas que contienen las confirmaciones de depuración, guarde y salga del editor.

Después de volver a basar, simplemente tire foo-merge en master:

git checkout master
git pull . foo-merge

2
2017-10-27 07:06



He tenido éxito con:

git rebase -p --onto SHA^ SHA

Dónde SHA es la confirmación que quieres eliminar

vía http://sethrobertson.github.io/GitFixUm/fixup.html#remove_deep


0
2018-04-08 09:47