Wenn Sie ein Commit an den Server schieben, und dann neu zu schreiben , die lokal zu begehen (mit git reset
, git rebase
, git filter-branch
oder jede andere Geschichte Manipulation), und dann schob die neu geschriebenen verpflichten zurück bis zu dem Server, wird schrauben Sie auf alle anderen , die gezogen hatte. Hier ist ein Beispiel; Angenommen, Sie haben A festgeschrieben und auf den Server übertragen.
- * - * - Ein <- Meister
- * - * - A <- Ursprung / Master
Jetzt beschließen Sie, A auf die von Ihnen erwähnte Weise neu zu schreiben, zurückzusetzen und erneut festzuschreiben. Beachten Sie, dass dies ein baumelndes Commit A hinterlässt, das schließlich als Müll gesammelt wird, da es nicht erreichbar ist.
-*-*-EIN
\.
Ein Meister
- * - * - A <- Ursprung / Master
Wenn jemand anderes, sagen wir Fred, master
währenddessen vom Server herunterfährt , hat er einen Verweis auf A, von dem aus er möglicherweise mit der Arbeit beginnt:
- * - * - Ein '<- Meister
- * - * - A <- Ursprung / Master
- * - * - AB <- Fred / Master
Wenn Sie nun in der Lage wären, Ihr A 'zum Ursprung / Master zu verschieben, was einen nicht schnellen Vorlauf erzeugen würde, hätte es kein A in seiner Geschichte. Wenn Fred also erneut versuchen würde zu ziehen, müsste er plötzlich zusammengeführt werden und würde das A-Commit wieder einführen:
- * - * - Ein '<- Meister
- * - * - A <- Ursprung / Master
- * - * - AB- \
\ * <- Fred / Master
EIN'--/
Wenn Fred dies bemerkt, könnte er eine Rebase durchführen, die verhindern würde, dass Commit A wieder erscheint. Aber er würde das bemerken und daran denken müssen; und wenn Sie mehr als eine Person haben, die A nach unten gezogen hat, müssten sie alle neu gründen, um zu vermeiden, dass das zusätzliche A-Commit in den Baum aufgenommen wird.
Daher ist es im Allgemeinen keine gute Idee, die Geschichte eines Repos zu ändern, aus dem andere Leute ziehen. Wenn Sie jedoch zufällig wissen, dass niemand anderes aus diesem Repo zieht (zum Beispiel ist es Ihr eigenes privates Repo, oder Sie haben nur einen anderen Entwickler, der an dem Projekt arbeitet, mit dem Sie sich leicht koordinieren können), können Sie dies mit Gewalt tun Update durch Ausführen von:
git push -f
oder
git push origin +master
Diese ignorieren beide die Überprüfung auf einen nicht schnellen Vorlauf und aktualisieren die Daten auf dem Server auf Ihre neue A'-Revision, wobei die A-Revision abgebrochen wird, damit sie schließlich als Müll gesammelt wird.
Es ist möglich, dass Force Pushs mit der receive.denyNonFastForwards
Konfigurationsoption vollständig deaktiviert werden . Diese Option ist standardmäßig für freigegebene Repositorys aktiviert. In diesem Fall ist es die beste Option, den Zweig zu löschen und ihn mit neu zu erstellen, wenn Sie einen Push wirklich erzwingen möchten git push origin :master; git push origin master:master
. Die denyNonFastForwards
Option ist jedoch aus einem oben beschriebenen Grund aktiviert. In einem gemeinsam genutzten Repository bedeutet dies, dass jetzt jeder, der es verwendet, sicherstellen muss, dass er auf den neuen Verlauf zurückgreift.
In einem gemeinsam genutzten Repository ist es im Allgemeinen besser, nur neue Commits nach oben zu verschieben, um das Problem zu beheben. Sie können git revert
Commits generieren, mit denen die Änderungen früherer Commits rückgängig gemacht werden.