git revierte varias confirmaciones específicas

4 minutos de lectura

El problema: una rama tiene buenas confirmaciones intercaladas con otras no deseadas.

Intento de solución:

git revert hash5 hash8 hash9 hash23

Lo que pensé que haría esto es que aplicaría todas las confirmaciones especificadas y luego me dejaría resolver cualquier conflicto.

Lo que ahora creo que sucede:

  • git aplica commit hash5, en el proceso introduciendo grandes conflictos.
  • Intento una fusión, edito el código como quiero que se vea, preparando el escenario para más conflictos (ver el siguiente punto)
  • git aplica commit hash8, que entra en conflicto con las ediciones realizadas en la fusión
  • Intento una fusión… etc etc

Pregunta: ¿Cómo hago para que git aplique todas las reversiones seguidas antes de presentarme posibles conflictos?

avatar de usuario
ntc2

Prueba de cordura

Primero, tenga en cuenta que git revert revierte sus parches en el orden en que enumera sus hashes; debe enumerar los hashes del más nuevo al más antiguo, ya que desea retroceder en el tiempo. Entonces, voy a llamar a tus hashes

<hash1> ... <hashN>

dónde <hash1> es más viejo que <hash2> … es más viejo que <hashN>. Entonces, asegúrese de estar haciendo

git revert <hashN> ... <hash1>

¡en primer lugar!

Solución fácil

En segundo lugar, asumiendo que los ha estado revirtiendo en el orden correcto, pruebe el --no-commit opción:

git revert --no-commit <hashN> ... <hash1>

Solución más complicada

En tercer lugar, si la solución fácil no funciona bien, pero las confirmaciones que desea revertir realmente tienen sentido como una única confirmación (si no, no veo muchas esperanzas), intente esto: cree una gran confirmación a partir de la cuatro que desea revertir y luego revertir la gran confirmación.

  1. Construye el gran compromiso:

    Cree una rama en el padre de la confirmación más antigua:

    git checkout -b big-commit <hash1>~
    

    Copie las confirmaciones en su nueva rama y colapselas:

    git cherry-pick --no-commit <hash1> ... <hashN>
    git commit -m "Big commit"
    

    Ahora deberías tener una gran confirmación en tu rama big-commit.

  2. Aplique el gran compromiso en reversa a la rama que está tratando de revertir:

    git checkout <branch you wanted to revert on>
    git revert big-commit
    

Otra solución relativamente fácil

Use el reajuste selectivo para reconstruir la rama en cuestión como si nunca hubiera contenido las confirmaciones no deseadas:

  1. Crear un nuevo rebuild sucursal para trabajar en:

    git checkout -b rebuild <branch you want to revert>
    
  2. Rebase de forma interactiva, descartando las confirmaciones que no desea:

    git rebase -i <hash1>~
    

    En el editor de rebase interactivo, elimine las líneas para <hash1><hashN>.

Ahora tu rebuild la rama contendrá <branch you want to revert>como si <hash1><hashN> nunca existió. Si te encuentras con conflictos aquí, parece que son inevitables.

Si necesita que su trabajo esté en <branch you want to revert>y no puedes simplemente git reset para apuntar a su nuevo rebuild rama:

git checkout <branch you want to revert>
git reset --hard rebuild

(por ejemplo, porque ya lo ha promovido públicamente), entonces puede aplicar las diferencias a <branch you want to revert> como parche:

git co <branch you want to revert>    
git diff <branch you want to revert> rebuild | patch

  • Tengo curiosidad: ¿el uso del comando cherry-pick en esta situación aún no generaría conflictos de fusión que deben resolverse manualmente a medida que se aplica cada confirmación? Pensé que el OP está tratando de evitar realizar tareas de fusión de procedimientos.

    – miqh

    27 de noviembre de 2013 a las 1:07

  • @miqid: ¡buena pregunta! Estaba asumiendo que los compromisos en sí mismos eran compatibles localmente / podrían aplicarse en orden desde algún punto de partida sin conflicto. Si ese no es el caso, no veo ninguna esperanza de evitar los conflictos.

    – ntc2

    27 de noviembre de 2013 a las 1:10


  • De hecho, antes de la fusión también probé una selección de cerezas. El resultado fue más o menos el mismo: me encontré resolviendo conflictos sin razón aparente.

    –Benjamin Burkhart

    27 de noviembre de 2013 a las 2:26

  • @BenjaminBurkhart: ¿probaste el --no-commit bandera con git revert o git cherry-pick? Tengo otra idea; Lo agrego arriba…

    – ntc2

    27 de noviembre de 2013 a las 5:09


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad