Git: Errore "Impossibile 'squash' senza un commit precedente" durante il rebase


96

Ho quanto segue nel testo delle cose da fare di git rebase -i HEAD~2:

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

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

Ora, quando provo a schiacciare il primo ( 56bcce7) e scelgo il secondo aggiungendo "s" prima del primo, ottengo il seguente errore:

Cannot 'squash' without a previous commit

Qualcuno può spiegarmi cosa significa e come lo faccio?

Voglio schiacciare il primo commit ( 56bcce7) e "selezionare e riformulare" il secondo e43cebacommit ( )


1
Cambia HEAD ~ 2 in HEAD ~ 3 se vuoi davvero schiacciare.
ElpieKay

1
E possibilmente usa --root, se HEAD ~ 2 è il tuo primo commit: stackoverflow.com/a/598788/2444812
Sybille Peters

Risposte:


81

Il rebase interattivo presenta i commit nell'ordine inverso a quello a cui sei abituato quando lo usi git log. git rebase -iriproduce i commit selezionati nell'esatto ordine (top-down) in cui sono elencati nel file di istruzioni rebase salvato. Quando si schiaccia, il commit selezionato per lo schiacciamento viene combinato con il commit che lo precede nell'elenco (modificato), ovvero il commit della riga precedente. Nel tuo caso, non esiste alcun commit precedente per 56bcce7. Devi eseguire una delle seguenti operazioni

  • git rebase -i HEAD~3(se si vuole schiacciare 56bcce7in 684f917)
  • Se intendi combinare 56bcce7con e43cebae e43cebanon dipende da 56bcce7, allora semplicemente riordinali:

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

    AGGIORNAMENTO : la risposta di Gus di seguito suggerisce un modo migliore di fare lo stesso, senza riordinare i due commit:

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

    Questo schiaccerà / unirà i due commit in uno. Quando il rebase interattivo richiede un messaggio di commit riformulato per 56bcce7, fornire il messaggio di commit che descrive l'unione di 56bcce7e e43ceba.


1
Voglio schiacciare 56bcce7 in e43ceba. Quindi, come eseguo il passaggio 1 qui?
Dawny33

83

Ho avuto un problema simile che ho risolto come segue:

Questo è il gruppo di commit che volevo eliminare:

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

Come puoi vedere, volevo no. 4, ma 1, 2 e 3 non avevano alcun commit precedente in cui schiacciarsi . Quindi il Impossibile 'squash' senza un precedente errore di commit .

La mia soluzione era utilizzare l' ropzione per# r, reword = use commit, but edit the commit message

Quindi il mio elenco di commit assomigliava a questo:

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

Dopo il salvataggio, la shell interattiva mi ha chiesto di riformulare il commit scelto.

Successivamente, il mio registro di commit ha prodotto un singolo commit che ha portato a una cronologia di commit più pulita.


2
come me se hai ricevuto un errore perché non hai scelto alcun impegno per riformulare o scegliere e ottenere l'errore menzionato (sulla domanda), dovrai fare git rebase --edit-todoe correggere riferendo questa risposta e poi faregit rebase --continue
vecchio monaco

Questa risposta è stata concisa e al punto, davvero aiutata, grazie
gonzofish

16

Ho avuto questo problema e il motivo per cui è successo nel mio caso è che non puoi schiacciare i commit più vecchi su un nuovo commit. Ecco un esempio diciamo che hai 3 commit:

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

Ora se dici git rebase -i HEAD~3e fai qualcosa di simile

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

Ciò comporterà l'errore:

errore: impossibile 'squash' senza un commit precedente Puoi risolvere questo problema con 'git rebase --edit-todo' e quindi eseguire 'git rebase --continue'. Oppure puoi interrompere il rebase con 'git rebase --abort'.

Soluzione:

Quando si schiacciano i commit, è necessario eliminare i commit recenti con quelli vecchi e non viceversa, quindi nell'esempio sarà qualcosa del genere:

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

Questo funzionerà bene, nel caso in cui desideri tutti i tuoi messaggi di commit, ti suggerirei di correggere invece di squash .


5
Grazie: non schiaccio i commit spesso e il consiglio di scegliere il commit più vecchio è ciò che mi ha aiutato a superare un errore git inutile.
0x574F4F54

3

Schiaccia con la logica inversa . Sarai in grado di selezionare il messaggio di commit desiderato nel passaggio successivo.

  • pickil primo commit per cui non vuoi il messaggio di commit.
  • squasho fixupil commit che desideri unire, fino a quello che contiene il messaggio di commit che desideri effettivamente.
pick 56bcce7 Closes #2774
squash e43ceba Lint.py: Replace deprecated link
  • confermare la modifica ( :x)
  • elimina i messaggi di commit che non desideri e lascia solo il messaggio dal commit che desideri (in questo caso:) Lint.py: Replace deprecated link.
  • confermare la scelta ( :x)

Spero sia più chiaro per qualcuno ✌🏽


1

Sarà meglio dire nell'editor interattivo che contiene i commit, git squash sempre dal basso verso l'alto e si dovrebbe lasciare una voce "pick" in alto per ricevere gli squash dal basso.


1

Ho appena provato questo approccio.

git log -n3

Questo mostrerebbe gli ultimi 3 commit che mi darebbero l'idea di qual è l'ultimo commit e quale è stato eseguito in precedenza. Ora ha dichiarato ribasando,

git rebase -i HEAD ~ 3

Scegli l'ultimo commit in cima al quale dobbiamo schiacciare gli altri due. L'ID del commit che viene scelto come commit di base sarebbe come,

scegli commit_id

Per gli altri due ID commit, cambiali in,

squash commit_id

o semplicemente,

s commit_id


0

Ho anche già incontrato questo problema proprio ora, è solo una disattenzione. Puoi risolvere il problema come di seguito: quando provi a schiacciare il primo (56bcce7) e scegli il secondo dovresti aggiungere "s" prima della seconda riga ma non il primo. puoi anche fare riferimento al prossimo sito web: http://backlogtool.com/git-guide/en/stepup/stepup7_5.html


1
Ciao ! Sarebbe meglio se effettui il checkout come creare un esempio minimo, completo e verificabile per sforzi futuri in Stack overflow. -Grazie
Momin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.