Solución:
Si no le importa crear una nueva rama, así es como manejé el problema:
Estar en la principal:
# create a new branch
git checkout -b new_clean_branch
# apply all changes
git merge original_messy_branch
# forget the commits but have the changes staged for commit
git reset --soft main
git commit -m "Squashed changes from original_messy_branch"
Muy bien, tengo la suficiente confianza para lanzar una respuesta. Tal vez tenga que editarlo, pero creo que sé cuál es su problema.
Su caso de prueba de repositorio de juguetes tiene una fusión; lo que es peor, tiene una fusión con conflictos. Y estás rebasando a través de la fusión. Sin -p
(que no funciona totalmente con -i
), las fusiones se ignoran. Esto significa que todo lo que hizo en la resolución de conflictos no esta ahi cuando la rebase intenta seleccionar la siguiente confirmación, por lo que es posible que su parche no se aplique. (Creo que esto se muestra como un conflicto de fusión porque git cherry-pick
puede aplicar el parche haciendo una combinación de tres vías entre la confirmación original, la confirmación actual y el ancestro común).
Desafortunadamente, como notamos en los comentarios, -i
y -p
(preservar fusiones) no se llevan muy bien. Sé que editar / reformular funciona y que reordenar no. Sin embargo, yo creer que funciona bien con calabazas. Esto no está documentado, pero funcionó para los casos de prueba que describo a continuación. Si su caso es mucho, mucho más complejo, es posible que tenga muchos problemas para hacer lo que quiere, aunque todavía será posible. (Moraleja de la historia: limpiar con rebase -i
antes de fusionándose.)
Entonces, supongamos que tenemos un caso muy simple, donde queremos aplastar juntos A, B y C:
- o - A - B - C - X - D - E - F (master)
/
Z -----------
Ahora, como dije, si no hubiera conflictos en X, git rebase -i -p
funciona como era de esperar.
Si hay conflictos, las cosas se complican un poco. Funcionará bien, pero luego, cuando intente recrear la fusión, los conflictos volverán a ocurrir. Tendrá que resolverlos nuevamente, agregarlos al índice y luego usar git rebase --continue
seguir adelante. (Por supuesto, puede resolverlos nuevamente consultando la versión de la confirmación de fusión original).
Si tienes rerere
habilitado en su repositoriorerere.enabled
establecido en verdadero), esto será mucho más fácil: git podrá reutilizar el recortado resolución de cuando originalmente tuvo los conflictos, y todo lo que tiene que hacer es inspeccionarlo para asegurarse de que funcionó correctamente, agregar los archivos al índice y continuar. (Incluso puedes ir un paso más allá, activando rerere.autoupdate
, y los agregará por usted, por lo que la combinación ni siquiera fallará). Sin embargo, supongo que nunca habilitó rerere, por lo que tendrá que resolver el conflicto usted mismo. *
* O puede probar el rerere-train.sh
script de git-contrib, que intenta “Prime [the] volver a recuperar la base de datos de las confirmaciones de combinación existentes “: básicamente, verifica todas las confirmaciones de combinación, intenta combinarlas y, si la combinación falla, toma los resultados y se los muestra a git-rerere
. Esto podría llevar mucho tiempo y nunca lo he usado, pero podría ser muy útil.
Estaba buscando un requisito similar, es decir, descartando las confirmaciones intermedias de mi rama de desarrollo, encontré que este procedimiento funcionó para mí.
en mi rama de trabajo
git reset –hard mybranch-start-commit
git checkout mybranch-end-commit . // files only of the latest commit
git add -a
git commit -m”New Message intermediate commits discarded”
viola, ¡hemos conectado la última confirmación con la confirmación de inicio de la rama! ¡No hay problemas de conflicto de fusión! En mi práctica de aprendizaje, he llegado a esta conclusión en esta etapa: ¿Existe un enfoque mejor para el propósito?