2012-03-21 30 views
192

Ho appena schiacciato alcuni commit con git rebase e ho fatto un git push --force (che è malvagio, lo so).Git pull dopo aggiornamento forzato

Ora gli altri ingegneri del software hanno una cronologia diversa e quando fanno un git pull, Git si fonderà. C'è un modo per risolvere questo problema, tranne fare un rm my-repo; git clone [email protected]:my-repo.git?

Ho bisogno di qualcosa come il contrario di git push --force, ma git pull --force non ha dato i risultati previsti.

+10

possono cancellare il loro ramo e crearlo anche senza dover cancellare l'intero repository: 'git checkout master && git branch -D test && git checkout -b test origine/test' – Florian

+1

Possibile duplicato di [Force Git to sovrascrivi i file locali su pull] (http://stackoverflow.com/questions/1125968/force-git-to-overwrite-local-files-on-pull) – gpoo

risposta

318

per ricevere il nuovo commit

git fetch 

Ripristina

È possibile ripristinare il commit per una filiale locale utilizzando git reset.

Per cambiare il commit di una filiale locale:

git reset origin/master --hard 

Attenzione però, come la documentazione mette:

Ripristina l'indice e albero di lavoro. Qualsiasi modifica ai file tracciati nell'albero di lavoro dal momento in cui il commit è < viene scartata.

Se si desidera mantenere effettivamente le modifiche apportate localmente, eseguire invece il ripristino --soft. Che aggiornerà la cronologia dei commit per il ramo, ma non cambierà alcun file nella directory di lavoro (e potrai quindi eseguirne il commit).

Rebase

È possibile riprodurre i tuoi commit locali in cima a qualsiasi altro commit/ramo utilizzando git rebase:

git rebase -i origin/master 

Questo invocherà rebase in modalità interattiva in cui è possibile scegliere come applicare ogni commit individuale che non è nella cronologia su cui ci si basa su di esso.

Se i commit che hai rimosso (con git push -f) sono già stati inseriti nella cronologia locale, saranno elencati come commit che verranno riapplicati - dovranno essere eliminati come parte del rebase o saranno semplicemente re -incluso nella cronologia per il ramo e riappare nella cronologia remota alla prossima pressione.

Utilizzare l'aiuto git command --help per ulteriori dettagli ed esempi su uno dei comandi precedenti (o altri).

+0

E se avessero già fatto dei commit locali? – iblue

+0

@iblue scegliere tra la perdita di tutte le modifiche, la rimozione della cronologia del commit ma la modifica del file o il tentativo di applicare ogni commit sulla parte superiore del nuovo head. L'opzione più semplice è probabilmente un soft reset. – AD7six

+0

@iblue Quando il tuo collega usa 'git reabse origin/master ', e intendi che ha già qualche commit prima, git scriverà il tuo commit sul retro del commit. – Tim

11

Questo non aggiusterà i rami che hanno già il codice che non vuoi (vedi sotto per come farlo), ma se hanno estratto un ramo e ora vogliono che sia pulito (e non "avanti" di origine/qualche ramo) allora è sufficiente:

git checkout some-branch # where some-branch can be replaced by any other branch 
git branch base-branch -D # where base-branch is the one with the squashed commits 
git checkout -b base-branch origin/base-branch # recreating branch with correct commits 

Nota: È possibile combinare tutti questi mettendo & & tra loro

Nota 2: Florian menzionato questo in un commento, ma chi legge commenti quando cerchi risposte?

Nota3: se si dispone di rami contaminati, è possibile crearne di nuovi basandosi sul nuovo "ramo stupido" e selezionandoli semplicemente con la selezione selettiva.

Es:

git checkout feature-old # some branch with the extra commits 
git log     # gives commits (write down the id of the ones you want) 
git checkout base-branch # after you have already cleaned your local copy of it as above 
git checkout -b feature-new # make a new branch for your feature 
git cherry-pick asdfasd # where asdfasd is one of the commit ids you want 
# repeat previous step for each commit id 
git branch feature-old -D # delete the old branch 

ora caratterizzano-nuovo è la vostra filiale, senza l'extra (forse male) commette!

+0

Questo è quello che volevo davvero. Qualcuno ha ribattezzato il ramo principale (chissà per quale motivo) ma non ho avuto modifiche locali su di esso che volevo commettere o altro. Quindi tutto quello che dovevo fare era cancellare il mio master branch locale (che si sentiva davvero strano) e fare di nuovo un checkout. Grazie! –

+0

@ peter-mortensen Le modifiche devono essere sostanziali in base a https://stackoverflow.com/help/editing –