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?
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.
-
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
.
-
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:
-
Crear un nuevo rebuild
sucursal para trabajar en:
git checkout -b rebuild <branch you want to revert>
-
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