Ein paar Hinweise zur Funktionsweise von Git (nicht technisch):
Wenn Sie die Basis neu festlegen, übernimmt git die fraglichen Commits und "schreibt" sie zusätzlich zu einem sauberen Verlauf erneut fest. Dies soll verhindern, dass der Verlauf angezeigt wird:
Description: tree -> mywork -> merge -> mywork -> merge -> mywork -> merge
Commit SHA1: aaaa -> bbbb -> cccc -> dddd -> eeee -> ffff -> gggg
Nach einer Rebase kann es so aussehen (oder ähnlich):
Description: tree -> rebase
Commit SHA1: aaaa -> hhhh
Das Problem ist, dass das neue Commit, das Sie dort veröffentlichen möchten, KEIN Nachkomme ist des Commits an der Spitze des Zweigs .
Jetzt wissen Sie, dass die gleichen Informationen in den Commits enthalten sind, aber git ist dafür verantwortlich, dass diese Commits nicht nur überschrieben werden (bbbb-gggg im obigen Beispiel).
Geteiltes Repo-Modell
Wenn Sie ein freigegebenes Repository verwenden, können solche Dinge sehr verwirrend werden. Lassen Sie mich erklären, warum. Angenommen, ein anderer Entwickler hat den Zweig heruntergezogen, und er hat in seiner Zweigstelle aaaa -> gggg festgeschrieben . Dann machen sie eine Verpflichtung iiii
In der Zwischenzeit haben Sie einen Stoß ausgeführt und einen Stoß erzwungen, wodurch der Baum folgendermaßen aussah:
Description: tree -> rebase
Commit SHA1: aaaa -> hhhh
Wenn der andere Entwickler versucht zu pushen, erhält er eine Meldung "Nicht schneller Vorlauf". Wenn er eine Zusammenführung durchführt, werden beide Historien miteinander verknüpft, und Sie geraten in ein Chaos
So etwas (chaotisch):
Description: tree -> rebase -> mywork -> merge -> mywork -> merge -> mywork -> merge -> devwork -> merge
Commit SHA1: aaaa -> hhhh -> bbbb -> cccc -> dddd -> eeee -> ffff -> gggg -> iiii -> jjjj
Mit anderen Worten, wenn andere ziehen UND drücken, ist es besser, dass Sie bis nach dem Rebase beim Git Merge bleiben oder PUSHING vermeiden (und nur Ihre Arbeit neu gründen).
Öffentlich sichtbares Repository-Modell
Vielleicht verwenden Sie ein anderes (gröberes) Modell, bei dem Sie nur möchten, dass die Leute aus Ihrem Repo ziehen können. In diesem Fall ist git push --force nicht schlecht, denn dann können sie damit umgehen. Sie können ihre Änderungen neu begründen , um sie auf Ihre Änderungen zu übertragen, bevor sie Ihnen ihre Patches geben. Es verhindert, dass Ihr Repo durcheinander gerät.
Es kann jedoch einen besseren Weg für Sie geben. Git Push - Spiegel
Von http://www.kernel.org/pub/software/scm/git/docs/git-push.html
Anstatt jede zu pushende Ref zu benennen, wird angegeben, dass alle Refs unter $ GIT_DIR / refs / (einschließlich, aber nicht beschränkt auf refs / Heads /, Refs / Remotes / und Refs / Tags /) in das Remote-Repository gespiegelt werden. Neu erstellte lokale Refs werden an das Remote-Ende verschoben, lokal aktualisierte Refs werden auf dem Remote-Ende zwangsweise aktualisiert und gelöschte Refs werden vom Remote-Ende entfernt. Dies ist die Standardeinstellung, wenn die Konfigurationsoption remote..mirror eingestellt ist.
Eines der großartigen Dinge an Git ist, dass es sehr flexibel ist und viele verschiedene Arten von Workflows ermöglicht. Die wahre Stärke liegt jedoch in der Tatsache, dass es sich um ein verteiltes Modell handelt. Ich glaube, dass der größte ROI erzielt werden kann, wenn es auf diese Weise verwendet wird.
git fetch, git rebase origin/master
, alle Ihre lokalen Konflikte mit dem Hauptzweig (zentralisiert) zu lösen und dann reine Commits zu pushen, die nur vorwärts gehen.git pull --rebase
hat einen ähnlichen Workflow. Dies ist eine leistungsstarke Option, aber Sie müssen vorsichtig damit sein, da das Zurücksetzen der falschen Dinge Commits umschreiben kann, die sich bereits im Ursprung / Master befinden. ZB andere Zweige nicht neu gründen, es sei denn, sie basieren zuerst auf dem aktuellen Ursprung / Master.