Se si preme un commit al server, e poi riscrivere quella commit a livello locale (con git reset
, git rebase
,git filter-branch
o qualsiasi altra manipolazione della storia), e poi spinto che impegnano riscritto il backup al server, si rovinare chiunque altro che aveva tirato. Ecco un esempio; diciamo di aver eseguito il commit di A e di averlo inviato al server.
- * - * - A <- maestro
- * - * - A <- origine / maestro
Ora decidi di riscrivere A, nel modo che hai menzionato, resettando e reimpegnando. Nota che questo lascia un commit penzolante, A, che alla fine verrà raccolto in modo spazzatura in quanto non è raggiungibile.
-*-*-UN
\
Un '<- maestro
- * - * - A <- origine / maestro
Se qualcun altro, diciamo Fred, tira giù master
dal server mentre stai facendo questo, avrà un riferimento ad A, da cui potrebbe iniziare a lavorare:
- * - * - A '<- master
- * - * - A <- origine / maestro
- * - * - AB <- fred / master
Ora, se tu fossi in grado di spingere la tua A 'su origin / master, il che creerebbe un avanzamento non veloce, non avrebbe A nella sua cronologia. Quindi, se Fred avesse provato a tirare di nuovo, avrebbe dovuto improvvisamente unire e reintrodurre il commit A:
- * - * - A '<- master
- * - * - A <- origine / maestro
- * - * - AB- \
\ * <- fred / master
UN'--/
Se Fred se ne accorge, allora potrebbe fare un rebase, che impedirebbe la ricomparsa del commit A. Ma avrebbe dovuto notarlo e ricordarsi di farlo; e se hai più di una persona che ha tirato giù A, dovrebbero tutte ribasare per evitare di ottenere il commit A extra nell'albero.
Quindi, in genere non è una buona idea cambiare la storia su un repo da cui attingono altre persone. Se, tuttavia, ti capita di sapere che nessun altro sta estraendo da quel repository (ad esempio, è il tuo repository privato o hai solo un altro sviluppatore che lavora al progetto con cui puoi coordinarti facilmente), allora puoi forzatamente aggiornare eseguendo:
git push -f
o
git push origin +master
Entrambi ignoreranno il controllo per un push non fast-forward e aggiorneranno ciò che è sul server alla tua nuova revisione A ', abbandonando la revisione A in modo che alla fine venga raccolta dalla spazzatura.
È possibile che i push push siano completamente disabilitati con l' receive.denyNonFastForwards
opzione di configurazione. Questa opzione è abilitata per impostazione predefinita nei repository condivisi. In tal caso, se vuoi davvero forzare un push, l'opzione migliore è eliminare il ramo e ricrearlo, con git push origin :master; git push origin master:master
. in ogni caso, ildenyNonFastForwards
opzione è abilitata per un motivo, descritto sopra; su un repository condiviso, significa che ora tutti coloro che lo utilizzano devono assicurarsi di rifarsi alla nuova storia.
In un repository condiviso, in genere è meglio inserire solo nuovi commit che risolvono qualsiasi problema tu abbia; è possibile utilizzare git revert
per generare commit che annulleranno le modifiche dei commit precedenti.