Rebasing und was bedeutet es, Push-Commits neu zu gründen?

109

Es wird oft gesagt, dass Sie Commits, die Sie bereits gepusht haben, nicht zurücksetzen sollten. Was könnte das bedeuten?

Hemant Kumar
quelle

Antworten:

80

Das ProGit-Buch hat eine gute Erklärung .

Die spezifische Antwort auf Ihre Frage finden Sie im Abschnitt " Die Gefahren des Wiederaufbaus ". Ein Zitat aus diesem Abschnitt:

Wenn Sie Inhalte neu erstellen, geben Sie vorhandene Commits auf und erstellen neue, die ähnlich, aber unterschiedlich sind. Wenn Sie Commits irgendwo pushen und andere sie nach unten ziehen und die Arbeit darauf aufbauen, und Sie diese Commits dann mit git rebase neu schreiben und wieder nach oben drücken, müssen Ihre Mitarbeiter ihre Arbeit neu zusammenführen, und die Dinge werden chaotisch, wenn Sie es versuchen ziehe ihre Arbeit zurück in deine.

Update:
Basierend auf Ihrem Kommentar unten scheint es, als hätten Sie Probleme mit Ihrem Git-Workflow. Hier sind einige Referenzen, die helfen können:

Tim Henigan
quelle
Danke für die Erklärung. Um mein Verständnis klarer zu machen, sollte ich, nachdem ich bestimmte Änderungen vorgenommen habe, nicht git rebase(--interactive?) Verwenden, um diesen Verlauf neu zu schreiben. Dies ist sicher ein Fehlerrezept. Andererseits, wenn ich bestimmte Änderungen am Thema neu festgelegt habe Verzweigen Sie (von Zweig X) und drücken Sie ihn. Es ist völlig normal, erneut zu starten, nachdem ein anderer Entwickler den Themenzweig geändert hat. Im Wesentlichen benutze ich seit einiger Zeit merge, aber wir sitzen im selben Boot wie darwinweb.net/articles/86 und die Geschichte ist fast unbrauchbar.
Hemant Kumar
@Hemant: Das Wiederherstellen von Commits nach dem Push auf ein öffentliches Repo ist im Allgemeinen eine schlechte Idee. Abgesehen davon klingt der Rat aus dem von Ihnen zitierten darwinweb-Artikel vernünftig, wenn Ihr Workflow ihrem ähnelt. In meiner aktualisierten Antwort finden Sie eine Liste anderer Referenzen, die möglicherweise hilfreich sind.
Tim Henigan
Bitte aktualisieren Sie einen Link zur "ProGit" -Seite über "Private Managed Team" auf git-scm.com/book/en/…
Eimantas
Technisch gesehen bleiben Git-Commits gleich, aber "Bestehende Commits aufgeben und neue erstellen, die ähnlich, aber unterschiedlich sind", sind nur dieselben Commits mit unterschiedlichen sha1-IDs? Nun, das wäre der einzig offensichtliche Weg, warum Kollaborateure ihre eigene Arbeit neu zusammenführen müssen!
Ciasto Piekarz
@Ciastopiekarz, das liegt daran, dass Sie den Verlauf im Upstream-Repo neu schreiben und die lokalen Repos anderer Entwickler möglicherweise Hinweise darauf haben. Jetzt sind ihre Zeiger veraltet: Der Git-Client hat keine andere Wahl, als ältere Zeiger zu verwenden und sich darauf zu verlassen, dass der Mensch den Rest erledigt. Dies ist eine erneute Zusammenführung, und es kann SEHR chaotisch sein mit vielen verwirrenden Änderungen, die manuell aussortiert werden müssen! Daher die Empfehlung, niemals etwas neu zu gründen, was bereits in ein Upstream-Repo verschoben wurde. Dies ist ein guter Rat und sollte nicht ignoriert werden, es sei denn, Sie sind ein Experte mit tiefem Wissen.
Forbin
240

Um dies zu verstehen, müssen wir ein bisschen verstehen, wie Git funktioniert. Ein Git-Repository ist eine Baumstruktur, bei der die Knoten des Baums Commits sind. Hier ist ein Beispiel für ein sehr einfaches Repository: Wenn du dich gabelst

Es gibt vier Commits im Hauptzweig, und jedes Commit hat eine ID (in diesem Fall a, b, c und d). Sie werden feststellen, dass d derzeit das letzte Commit (oder HEAD) des Hauptzweigs ist. Geben Sie hier die Bildbeschreibung ein

Hier haben wir zwei Zweige: Master und My-Zweig. Sie können sehen, dass Master und My-Branch Commits a und b enthalten, aber dann beginnen sie zu divergieren: Master enthält c und d, während My-Branch e und f enthält. b soll die "Merge-Basis" meines Zweigs im Vergleich zum Master sein - oder häufiger nur die "Basis". Es macht Sinn: Sie können sehen, dass my-branch auf einer früheren Version von master basiert.

Nehmen wir also an, mein Zweig ist veraltet und Sie möchten ihn mit der neuesten Version von master auf den neuesten Stand bringen. Anders ausgedrückt, mein Zweig muss c und d enthalten. Sie könnten eine Zusammenführung durchführen, dies führt jedoch dazu, dass der Zweig seltsame Zusammenführungs-Commits enthält, die das Überprüfen der Pull-Anforderung erheblich erschweren. Stattdessen können Sie eine Rebase durchführen.

Geben Sie hier die Bildbeschreibung ein

Wenn Sie neu gründen, findet git die Basis Ihres Zweigs (in diesem Fall b), findet alle Commits zwischen dieser Basis und HEAD (in diesem Fall e und f) und spielt diese Commits auf dem HEAD des Zweigs erneut ab Sie basieren auf (in diesem Fall Master). Git erstellt tatsächlich neue Commits, die darstellen, wie Ihre Änderungen über dem Master aussehen: Im Diagramm werden diese Commits als e 'und f' bezeichnet. Git löscht Ihre vorherigen Commits nicht: e und f bleiben unberührt, und wenn bei der Rebase etwas schief geht, können Sie direkt zu dem zurückkehren, was früher war.

Wenn viele verschiedene Personen gleichzeitig an einem Projekt arbeiten, können Pull-Anforderungen schnell veralten. Eine "veraltete" Pull-Anforderung ist nicht mehr mit der Hauptentwicklungslinie auf dem neuesten Stand und muss aktualisiert werden, bevor sie in das Projekt integriert werden kann. Der häufigste Grund, warum Pull-Anforderungen veraltet sind, liegt in Konflikten: Wenn zwei Pull-Anforderungen ähnliche Zeilen in derselben Datei ändern und eine Pull-Anforderung zusammengeführt wird, tritt bei der nicht zusammengeführten Pull-Anforderung jetzt ein Konflikt auf. Manchmal kann eine Pull-Anforderung ohne Konflikte veraltet sein: Möglicherweise erfordern Änderungen in einer anderen Datei in der Codebasis entsprechende Änderungen in Ihrer Pull-Anforderung, um der neuen Architektur zu entsprechen, oder der Zweig wurde erstellt, als jemand versehentlich fehlgeschlagene Komponententests mit dem zusammengeführt hat Hauptzweig. Unabhängig vom Grund

PseudoCoder
quelle
68

Durch erneutes Basieren wird der Verlauf neu geschrieben. Wenn niemand etwas über diese Geschichte weiß, ist das vollkommen in Ordnung. Wenn diese Geschichte jedoch öffentlich bekannt ist, funktioniert das Umschreiben der Geschichte in Git genauso wie in der realen Welt: Sie brauchen eine Verschwörung.

Verschwörungen sind wirklich schwer zusammenzuhalten, deshalb vermeiden Sie es besser, öffentliche Zweige überhaupt neu zu gründen.

Beachten Sie, dass es sind Beispiele für erfolgreiche Verschwörungen: Der puZweig der Junio C. Hamano git - Repository (das offizielle Repository des Git SCM) wird häufig indexiert. Dies funktioniert so, dass so ziemlich jeder, der sie verwendet, puauch die Git-Entwickler-Mailingliste abonniert hat und die Tatsache, dass der puZweig neu basiert, auf der Mailingliste und der Git-Website weit verbreitet ist.

Jörg W Mittag
quelle
4
+1. Ich denke, der puZweig von git.git ist ein äußerst hilfreiches Beispiel für die Verwendung von Rebase in einem (öffentlichen) Workflow. Für diejenigen, die nicht damit vertraut sind, besteht die allgemeine Idee darin, Themenzweige, in denen keine Commits vorhanden sind next(der instabile Zweig unmittelbar vor dem Zusammenführen mit dem Master), neu zu gründen und dann den puZweig durch Zurücksetzen auf nextund Zusammenführen aller Themenzweige neu zu erstellen . (Quelle: Documentation / howto /tenance-git.txt git.kernel.org/?p=git/git.git;a=blob;f=Documentation/howto/… )
Cascabel
25
+1 für "Das Umschreiben der Geschichte in Git funktioniert genauso wie in der realen Welt: Sie brauchen eine Verschwörung"
Sleeper Smith
"Eine öffentliche Ankündigung ist nicht erforderlich, da pu wie oben beschrieben ein Wegwerfzweig ist." git-scm.com/docs/gitworkflows Wir machen etwas Ähnliches bei der Arbeit. "TEMP-etwas-Neuestes" ist ein Wegwerfzweig , der eine Kombination der neuesten Änderungen darstellt. Es kann sich um eine Zusammenführung mehrerer Funktionszweige handeln. Möglicherweise wird er gelöscht und zu jedem Zeitpunkt neu erstellt und sollte nicht weiterentwickelt werden.
Pilkch
6

Eine Rebase ändert den Verlauf Ihres Repositorys. Wenn Sie Commits an die Welt senden, dh sie anderen zur Verfügung stellen und dann Ihre Sicht auf den Commit-Verlauf ändern, wird es schwierig, mit jemandem zusammenzuarbeiten, der Ihren alten Verlauf hat.

Rebase als schädlich angesehen, ist eine gute Übersicht, denke ich.

dsolimano
quelle