Git: error "No se puede 'aplastar' sin una confirmación previa" mientras se reajusta

96

Tengo lo siguiente en el texto de tareas pendientes de git rebase -i HEAD~2:

pick 56bcce7 Closes #2774
pick e43ceba Lint.py: Replace deprecated link

# Rebase 684f917..e43ceba onto 684f917 (2 command(s))
#
...

Ahora, cuando trato de aplastar el primero ( 56bcce7) y elijo el segundo agregando "s" antes del primero, aparece el siguiente error:

Cannot 'squash' without a previous commit

¿Alguien puede explicarme qué significa y cómo lo hago?

Quiero aplastar la primera confirmación ( 56bcce7) y "seleccionar y reformular" la segunda ( e43ceba) confirmación

Dawny33
fuente
1
Cambie HEAD ~ 2 a HEAD ~ 3 si realmente quiere aplastar.
ElpieKay
1
Y posiblemente use --root, si HEAD ~ 2 es su primera confirmación: stackoverflow.com/a/598788/2444812
Sybille Peters

Respuestas:

81

La rebase interactiva presenta las confirmaciones en el orden inverso al que está acostumbrado cuando usa git log. git rebase -ireproduce las confirmaciones seleccionadas en el orden exacto (de arriba hacia abajo) en que aparecen en el archivo de instrucciones de rebase guardado. Al aplastar, la confirmación seleccionada para aplastar se combina con la confirmación que la precede en la lista (editada), es decir, la confirmación de la línea anterior. En su caso, no hay confirmación previa para 56bcce7. Tienes que hacer una de las siguientes

  • git rebase -i HEAD~3(si quiere aplastar 56bcce7a 684f917)
  • Si desea combinar 56bcce7con e43ceba, y e43cebano depende de 56bcce7, simplemente reordenarlos:

    r e43ceba Lint.py: Replace deprecated link
    s 56bcce7 Closes #2774
    

    ACTUALIZACIÓN : la respuesta de Gus a continuación sugiere una mejor manera de hacer lo mismo, sin reordenar las dos confirmaciones:

    r 56bcce7 Closes #2774
    s e43ceba Lint.py: Replace deprecated link
    

    Esto aplastará / fusionará las dos confirmaciones en una. Cuando la rebase interactiva solicite un mensaje de confirmación reformulado 56bcce7, proporcione el mensaje de confirmación que describe la unión de 56bcce7y e43ceba.

León
fuente
1
Quiero aplastar 56bcce7 al e43ceba. Entonces, ¿cómo hago el Paso 1 aquí?
Dawny33
83

Tuve un problema similar que resolví de la siguiente manera:

Este es el grupo de confirmación que quería aplastar:

1 s 01cc5a08 Removes open div
2 s a2b6eecf Restores old fonts
3 s 603479ff Cleans left out div
4 pick 5afdbc33 Update: show logo on landing page
5 s 04c1cb13 change version of dev and prod from 1 to 2
6 s bbe6a8f8 Update: show logo on landing page if they have one
7 s c0d6008a Adds check for C users

Como puede ver, no quería. 4, pero 1, 2 y 3 no tenían compromisos previos para jugar . Por lo tanto, no se puede 'aplastar' sin un error de confirmación previo .

Mi solución fue usar la ropción para# r, reword = use commit, but edit the commit message

Entonces mi lista de confirmaciones se veía así:

1 r 01cc5a08 Removes open div
2 s a2b6eecf Restores old fonts
3 s 603479ff Cleans left out div
4 s 5afdbc33 Update: show logo on landing page
5 s 04c1cb13 change version of dev and prod from 1 to 2
6 s bbe6a8f8 Update: show logo on landing page if they have one
7 s c0d6008a Adds check for C users

Después de guardar, el shell interactivo me pidió la nueva redacción de la confirmación elegida.

Después de eso, mi registro de confirmaciones resultó en una única confirmación que resultó en un historial de confirmaciones más limpio.

Gus
fuente
2
como yo, si obtuvo un error porque no eligió ningún compromiso para reformular o elegir y obtener el error mencionado (en la pregunta), deberá hacer git rebase --edit-todoy corregir esta respuesta y luego hacerlogit rebase --continue
old-monk
Esta respuesta fue concisa y al grano, realmente ayudó, gracias
gonzofish
16

Tuve este problema y la razón por la que sucedió en mi caso fue que no se pueden aplastar confirmaciones anteriores en una nueva confirmación. Aquí hay un ejemplo que dice que tiene 3 confirmaciones:

1 pick 01mn9h78 The lastest commit
2 pick a2b6pcfr A commit before the latest
3 pick 093479uf An old commit i made a while back

Ahora si dices git rebase -i HEAD~3y haces algo como

1 pick 01mn9h78 The lastest commit
2 s a2b6pcfr A commit before the latest
3 s 093479uf An old commit i made a while back

Esto resultará en el error:

error: no se puede 'aplastar' sin una confirmación previa. Puede solucionar este problema con 'git rebase --edit-todo' y luego ejecutar 'git rebase --continue'. O puede abortar la rebase con 'git rebase --abort'.

Solucion:

Al aplastar las confirmaciones, debe aplastar las confirmaciones recientes con las antiguas y no al revés, por lo que en el ejemplo será algo como esto:

1 s 01mn9h78 The lastest commit
2 s a2b6pcfr A commit before the latest
3 pick 093479uf An old commit i made a while back

Esto funcionará bien, en caso de que desee todos sus mensajes de confirmación, sugeriría que se arreglen en lugar de aplastar .

DvixExtract
fuente
5
Gracias, no aplasto las confirmaciones a menudo y el consejo de elegir la confirmación más antigua es lo que me ayudó a superar un error de git inútil.
0x574F4F54
3

Aplasta con la lógica inversa . Podrá seleccionar el mensaje de confirmación deseado en el paso posterior.

  • pickla primera confirmación para la que no desea el mensaje de confirmación.
  • squasho fixuplas confirmaciones que desea fusionar, hasta la que tenga el mensaje de confirmación que realmente deseaba.
pick 56bcce7 Closes #2774
squash e43ceba Lint.py: Replace deprecated link
  • confirmar el cambio ( :x)
  • elimine los mensajes de confirmación que no desee y deje solo el mensaje de confirmación que desee (en este caso :) Lint.py: Replace deprecated link.
  • confirmar la elección ( :x)

Espero que sea más claro para alguien ✌🏽

Kamafeather
fuente
1

Será mejor decir en el editor interactivo que contiene las confirmaciones, git siempre aplasta de abajo hacia arriba y uno debe dejar una entrada de "selección" en la parte superior para recibir las combinaciones desde abajo.

ekyu88
fuente
1

Solo probé este enfoque.

git log -n3

Esto mostraría las últimas 3 confirmaciones, lo que me daría una idea de cuál es la última confirmación y cuál fue anteriormente. Ahora dicho rebase,

git rebase -i HEAD ~ 3

Elija la última confirmación además de la que necesitamos aplastar las otras dos. El ID de confirmación que se elige como confirmación base sería como,

elegir commit_id

Para los otros dos ID de confirmación, cámbielos a,

squash commit_id

o simplemente,

s commit_id

Tom Taylor
fuente
0

También me he encontrado con este problema en este momento, eso es simplemente un descuido. Puede resolver el problema como el siguiente: cuando intente aplastar el primero (56bcce7) y elija el segundo, debe agregar "s" antes de la segunda línea, pero no el primero. también puede consultar el siguiente sitio web: http://backlogtool.com/git-guide/en/stepup/stepup7_5.html

usuario8073722
fuente
1
Hola ! Sería mejor si revisa Cómo crear un ejemplo mínimo, completo y verificable para esfuerzos futuros en Stack overflow. -Gracias
Momin