Come rimuovere il primo commit in git?


179

Sono curioso di sapere come rimuovere il primo commit in git.

Qual è la revisione prima di commettere qualcosa? Questa revisione ha un nome o un tag?


2
Tanto per cominciare, dovresti sapere che la revisione non ha senso. Puoi parlare di commit o dei loro SHA relativi. Inoltre, perché dovresti farlo? Il primo commit è quello su cui tutto è costruito. È possibile eliminare alcuni commit insieme, incluso il primo commit, che diventa il nuovo primo commit, ma cosa significa persino eliminare il primo commit (o eliminare qualsiasi altro tranne l'ultimo)?
Shahbaz,

@Shahbaz sì, questo è il modo migliore, guarda qui per esempio: ariejan.net/2011/07/05/git-squash-your-latests-commits-into-one
timaschew

5
È possibile utilizzare git rebase -i --root. Vedere la seguente risposta SO per i dettagli: stackoverflow.com/questions/2246208/...
MKroehnert


Questa risposta ha la soluzione corretta per eliminare il commit radice del ramo corrente:git filter-branch --parent-filter "sed 's/-p <the_commit>//'" HEAD
Jody Bruchon,

Risposte:


321

Per me, il modo più sicuro è usare il update-refcomando:

git update-ref -d HEAD

Eliminerà il riferimento nominato HEAD, quindi ripristinerà (dolcemente, non perderai il tuo lavoro) tutti i tuoi commit della tua attuale filiale .

Se quello che vuoi è unire il primo commit con il secondo, puoi usare il rebasecomando:

git rebase -i --root

Un ultimo modo potrebbe essere quello di creare una succursale orfana, una succursale con lo stesso contenuto ma senza cronologia di commit e impegnare il tuo nuovo contenuto su di essa:

git checkout --orphan <new-branch-name>

7
Peccato che questa non sia la risposta accettata. È anche un peccato che la maggior parte dei successi su Google più o meno dica "non puoi annullare il primo commit". Questo ha fatto il trucco per me. Grazie!
danielpops,

1
Grazie @danielpops per il tuo supporto! È bello notare che ho risposto a questa domanda 3 anni dopo. Git si è evoluto nel frattempo.
Tzi,

Ho usato rebase, contrassegnato il secondo commit come "squash", quindi ho fatto una spinta --force all'origine. Grazie!
Philip Atz,

1
git update-ref -d HEAD è il modo più sicuro per rimuovere tutta la cronologia, non solo il commit iniziale.
user1767316

L'ho fatto e ha eliminato tutti i miei file che ho aggiunto al primo commit. Triste. Almeno non era molto
Vyacheslav Tsivina, il

42

Non c'è nulla prima del primo commit, poiché ogni commit fa riferimento a un commit parent. Questo rende speciale il primo commit (un commit orfano), quindi non c'è modo di fare riferimento a uno "stato" precedente.

Quindi, se vuoi correggere il commit, puoi semplicemente git commit --amend: questo modificherà il commit senza crearne un altro.

Se vuoi solo ricominciare tutto da capo, elimina il .gitrepository e creane un altro congit init


7
Questa risposta è errata: esiste un modo per tornare allo stato prima del primo commit. Vedi la risposta di tzi sotto.
David Nelson,

2
--amendL'inoltre, non aggiornerà l'autore correttamente se è stato inizialmente configurato correttamente. Questo è quello di cui avevo bisogno, quindi ho usato la risposta accettata e poi ho fatto un nuovo commit.
Mark Edington,

11
# Check out to a temporary branch:
git checkout --orphan TEMP_BRANCH

# Add all the files:
git add -A

# Commit the changes:
git commit -am "Initial commit"

# Delete the old branch:
git branch -D master

# Rename the temporary branch to master:
git branch -m master

# Finally, force update to our repository:
git push -f origin master

3
Non una risposta: la domanda era "come rimuovere il primo commit" e non "come eliminare tutto tranne l'ultimo commit".
Peter - Ripristina Monica l'

1
Stavo cercando esattamente questo. Grazie!
Krzysztof Tomaszewski,

6

Potresti semplicemente modificare il tuo primo commit (dato che c'è sempre un primo commit in un repository git). Prendi in considerazione l'uso git commit --amend --reset-authorinvece del solito git commit --amend.


1
Non una risposta: la domanda voleva eliminare il primo commit e non modificare le proprietà dell'ultimo.
Peter - Ripristina Monica l'

@ peterh-ReinstateMonica Per chiarimenti: gli commit possono essere modificati durante il rebase interattivo per cambiare completamente il loro contenuto, ma è necessario fornire anche --reset-author per cambiare l'autore. Con ciò, puoi sostituire completamente il primo commit a tuo piacimento. Vedi anche la risposta di CharlesB.
Max Beikirch,

3

Stavo cercando un modo per annullare tutte le commit git da un repository, come se non fossero mai avvenute.

Rebasing funzionerà fino a un certo punto. Tuttavia, il primo (cronologicamente il più vecchio git commit) sarà sempre problematico, dal momento che non ha un genitore, quindi questo si risolverà.

Nessuna di queste risposte mi ha risolto del tutto. Ma dopo molte ricerche e prove ed errori, ho scoperto che questo funzionava!

git update-ref -d HEAD
git push origin master -f

Spero che questo ti aiuti. Vi auguro una buona giornata.


1
Per essere chiari per chiunque legga questa risposta: questo cancella ogni commit, ma OP vuole solo cancellare il primo commit effettuato su un repository; non eseguirlo per eliminare il primo commit perché eliminerà TUTTI i commit.
Jody Bruchon,

2

Un altro modo che puoi fare è:

  1. Acquista in una filiale che desideri mantenere (ad esempio dev) git checkout dev
  2. Ora elimina il ramo che desideri ripristinare git branch -D master
  3. Ora crea un ramo vuoto con lo stesso nome git checkout --orphan master

Ovviamente, tutto ciò dipenderebbe dal tuo caso d'uso, ma se hai più di un ramo, eliminare la .gitdirectory non ha senso.


3
Dopo aver fatto ciò, è necessario eliminare il ramo in remoto prima di premere. Altrimenti, quando provi a spingere avrai questo errore:! [rifiutato] master -> master (non avanzamento rapido) - errore: impossibile inviare alcuni riferimenti a 'git@github.com: r1 / r2.git' - suggerimento: gli aggiornamenti sono stati rifiutati perché la punta del ramo corrente è dietro - suggerimento: la sua controparte remota. Integra le modifiche remote (ad es. Suggerimento: 'git pull ...') prima di premere di nuovo ... - Se esegui un git pull, tutti i commit tornano indietro.
dxvargas,

2

Se si desidera mantenere altri rami, ma ad esempio far masterricominciare il ramo senza una cronologia comune ad altri rami, un modo sicuro per raggiungere questo obiettivo è quello di creare un nuovo repository e spingerne il contenuto nel vecchio:

cd ..
git init newrepo
cd newrepo
# make some initial commits
git push ../oldrepo master:newmaster

Questo crea un newmasterramo nel vecchio repository, con una storia che non è comune a nessuno degli altri rami. Ovviamente, puoi anche sovrascrivere masteranche con git push -f.

Se vuoi distruggere tutti i rami e tutti i contenuti esistenti, esegui semplicemente

rm -rf .git/

1
Non una risposta: l'OP voleva rimuovere il primo commit e non avviare un nuovo repository git con l'albero di lavoro corrente come commit iniziale.
Peter - Ripristina Monica l'

@peterh Sono d'accordo git rebase --rootè probabilmente ciò che OP voleva, ma considerando questa risposta ha due voti positivi, mi asterrò dall'eliminarlo nel caso in cui qualcuno lo ritenga ancora rilevante.
user1338062,

Penso che questa risposta è esattamente rilevante - se si desidera eliminare il primo commit in qualche ramo, e non v'è un solo commettere! (Ma vuoi anche mantenere gli altri commit in altri rami; e vuoi anche farlo in modo che i cambiamenti finiscano in Bitbucket o Github, non solo localmente.) Credo che questa risposta sia un modo per farlo, e Penso che potrebbe essere l'unico modo qui per farlo. (Questo perché - anche per quanto posso vedere - non c'è modo di forzare il push di una filiale locale senza commit su una filiale remota con alcuni commit.)
MikeBeaton,

0

Se l'hai appena commesso ma non lo hai spinto, rimuovi semplicemente la directory .git e di git initnuovo ...


@peterh Sì. Stai assumendo (penso) che la domanda del PO riguardi il voler eliminare il primo commit ma mantenere i commit successivi. Un'altra possibilità (che penso corrisponda perfettamente alla domanda del PO - e alla quale questa risposta è una risposta) è voler eliminare il primo e solo commit da un ramo, ripristinandolo nuovamente completamente vuoto.
MikeBeaton,

@MikeBeaton Hai ragione. Rimuovo il mio commento, ma poi ho bisogno di votare per chiudere la domanda come poco chiara. Nota, anche se solo io mi è stato fatto questo commento, ma dietro di me ci sono 40000 visitatori e una parte significativa di loro ha trovato questa domanda con Google - e non hanno ottenuto quello che volevano.
Peter - Ripristina Monica il

Sembra estremo. Elimina la domanda? Non si potrebbe (perfettamente bene) sostenere che una risposta completa a una domanda perfettamente ragionevole è che ci sono due approcci diversi che devono essere adottati, a seconda se ... ecc.? (Voglio dire, io, per esempio, vorrei sapere come rimuovere il primo commit quando non è l'unico commit, e anche come rimuovere il primo commit quando è l'unico commit. Non è certamente ovvio, e dipende sicuramente sui dettagli specifici dell'implementazione, che in realtà risulta che in ciascun caso sono necessari approcci piuttosto diversi.)
MikeBeaton

0

La risposta alla domanda dipende dal fatto che:

  • Si desidera rimuovere il primo e SOLO commit su un ramo (lasciando gli altri rami com'erano) o se

  • Si desidera rimuovere il primo commit su alcuni branch, mentre 'lasciando sul posto' i commit successivi (e gli altri branch).

Il secondo è relativamente più semplice. In sostanza, devi fare un passo indietro per fare il root - la maggior parte delle risposte qui sono sui modi per farlo.

Fare il secondo (rimuovere il primo e impegnare solo da un ramo lasciando altri rami da solo) è più difficile. O, almeno, particolarmente difficile se vuoi che accada e che il cambiamento si rifletta in GitHub o Bitbucket. Non c'è (per quanto posso dire) in Git alcun modo di spingere o forzare spingere un ramo senza commit. E non c'è (ancora una volta, per quanto posso vedere) alcun modo per creare un nuovo ramo vuoto senza alcun commit su di esso in GitHub o Bitbucket. Quindi, in sostanza, devi creare un nuovo repository per creare un ramo completamente vuoto, quindi aggiungere nuovamente i rami che desideri (inclusi i commit che desideri), secondo la risposta di @ user1338062.

Quindi spero che questa risposta chiarisca ciò che potrebbe non essere stato ovvio: che ci sono due approcci diversi che devono essere adottati, per due diversi scenari (più o meno ragionevoli) che sono entrambe cose che potresti voler essere in grado di fare, al fine padroneggiare pienamente facendo ciò che l'OP chiede.

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.