Resumen
El mensaje de error
No se puede 'aplastar' sin una confirmación previa
significa que probablemente intentaste "aplastar hacia abajo". Git siempre aplasta una confirmación más nueva en una confirmación más antigua o "hacia arriba" como se ve en la lista interactiva de tareas de rebase, es decir, en una confirmación en una línea anterior. Cambiar el comando en la primera línea de tu lista de tareas squash
siempre producirá este error, ya que no hay nada en lo que pueda comprometerse el primer commit.
La solución
Primero regrese a donde comenzó
$ git rebase --abort
Digamos que tu historia es
$ git log --pretty=oneline
a931ac7c808e2471b22b5bd20f0cad046b1c5d0d c
b76d157d507e819d7511132bdb5a80dd421d854f b
df239176e1a2ffac927d8b496ea00d5488481db5 a
Es decir, a fue el primer commit, luego b, y finalmente c. Después de cometer c, decidimos aplastar b y c juntos:
(Nota: Ejecutar git log
canaliza su salida en un buscapersonas, less
de manera predeterminada en la mayoría de las plataformas. Para salir del buscapersonas y volver al símbolo del sistema, presione la q
tecla).
Correr git rebase --interactive HEAD~2
te da un editor con
pick b76d157 b
pick a931ac7 c
# Rebase df23917..a931ac7 onto df23917
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
(Tenga en cuenta que esta lista de tareas está en el orden inverso en comparación con la salida de git log
).
Cambiar las b pick
a squash
resultará en el error que viste, pero si en cambio aplastas c en b (el más nuevo se compromete en el anterior o "aplasta hacia arriba") al cambiar la lista de tareas a
pick b76d157 b
squash a931ac7 c
y guardar-salir de su editor, obtendrá otro editor cuyos contenidos son
# This is a combination of 2 commits.
# The first commit's message is:
b
# This is the 2nd commit message:
c
Cuando guarda y sale, el contenido del archivo editado se convierte en mensaje de confirmación de la nueva confirmación combinada:
$ git log --pretty=oneline
18fd73d3ce748f2a58d1b566c03dd9dafe0b6b4f b and c
df239176e1a2ffac927d8b496ea00d5488481db5 a
Nota sobre la reescritura del historial
El rebase interactivo reescribe la historia. Intentar pasar a un control remoto que contiene el historial anterior fallará porque no es un avance rápido.
Si la rama que usted reformuló es una rama de tema o característica en la que está trabajando solo , no es gran cosa. Empujar a otro repositorio requerirá la --force
opción, o alternativamente, según los permisos del repositorio remoto, es posible que pueda eliminar primero la rama anterior y luego empujar la versión modificada. Los ejemplos de esos comandos que potencialmente destruirán el trabajo están fuera del alcance de esta respuesta.
Reescribir el historial ya publicado en una rama en la que está trabajando con otras personas sin una muy buena razón, como filtrar una contraseña u otros detalles confidenciales, obliga a sus colaboradores a trabajar y es antisocial y molestará a otros desarrolladores. La sección "Recuperación de una base de datos ascendente" en la git rebase
documentación explica, con énfasis adicional.
Rebasar (o cualquier otra forma de reescribir) una rama en la que otros han basado el trabajo es una mala idea: cualquiera que esté aguas abajo se ve obligado a corregir manualmente su historial. En esta sección se explica cómo hacer la corrección desde el punto de vista aguas abajo. La solución real, sin embargo, sería evitar rebasear el flujo ascendente en primer lugar. ...