Wie kann ich Git Rebase verwenden, ohne dass ein erzwungener Push erforderlich ist?

92

In einem Versuch, Git Nirvana zu erreichen, verbringe ich den Tag damit, zu lernen, wie man Rebase für Situationen nutzt, in denen ich gerade fusioniere.

Wenn ich einen meiner Meinung nach git 101-Flow durchlaufe (den ich unten darlege), muss ich push --forcemeine Änderungen auf den Ursprung zurückschieben.

Ich bin nicht der einzige - ich weiß, dass dies überdachter Boden ist (siehe 1 , 2 , 3 , 4 , 5 ), und ich verstehe die technischen Gründe, warum eine Kraft notwendig ist. Mein Problem ist folgendes: Es gibt viele (viele) Blogeinträge, die das Lob der Rebase singen und wie es ihr Leben verändert hat (siehe 1 , 2 , 3 , 4, um einige aufzulisten ), aber keiner von ihnen erwähnt, dass dies push --forceTeil davon ist ihr Fluss. Fast jede Antwort auf die vorhandenen Fragen zum Stapelüberlauf sagt jedoch Dinge wie "Ja, wenn Sie neu aufbauen wollen, müssen Sie sie verwenden push --force".

Angesichts der Anzahl und Religiosität von Rebase-Befürwortern muss ich glauben, dass die Verwendung von Push-Force kein fester Bestandteil eines Rebase-Flusses ist und dass sie etwas falsch machen, wenn man ihre Pushs oft erzwingen muss .

push --forceist eine schlechte Sache .

Also hier ist mein Fluss. Auf welche Weise könnte ich ohne Kraft die gleichen Ergebnisse erzielen?

Einfaches Beispiel

Zwei Zweige:

  • v1.0 - ein Release-Zweig, der nur Patches enthält
  • Master - alles für die nächste Hauptversion.

Ich habe ein paar Patch-Commits und ein paar Commits für die nächste Version.

Premerge

Ich möchte die Patches in meinen Master integrieren, damit sie für die nächste Version nicht verloren gehen. Vorerleuchtung Ich würde einfach:

git checkout master
git merge v1.0

Aber jetzt versuche ich es

git checkout master
git rebase v1.0

Also jetzt bin ich hier:

Geben Sie hier die Bildbeschreibung ein

Zeit für:

git push

Kein Würfel.

Roy Truelove
quelle

Antworten:

43

Rebasing ist ein großartiges Tool, aber es funktioniert am besten, wenn Sie damit Schnellvorlaufzusammenführungen für Themenzweige auf Master erstellen. Beispielsweise können Sie Ihren Zweig zum Hinzufügen eines neuen Widgets gegen den Master neu gründen:

git checkout add-new-widget
git rebase -i master

bevor Sie einen schnellen Vorlauf des Zweigs in den Master durchführen. Beispielsweise:

git checkout master
git merge --ff-only add-new-widget

Dies hat den Vorteil, dass Ihr Verlauf nicht viele komplexe Zusammenführungs-Commits oder Zusammenführungskonflikte aufweist, da alle Ihre Änderungen vor dem Zusammenführen auf die Spitze des Masters übertragen werden. Ein sekundärer Vorteil besteht darin, dass Sie die Basis neu festgelegt haben, diese jedoch nicht verwenden müssen, git push --forceda Sie den Verlauf in der Hauptniederlassung nicht beeinträchtigen.

Dies ist sicherlich nicht der einzige Anwendungsfall für Rebase oder der einzige Workflow, aber es ist eine der sinnvolleren Anwendungen dafür, die ich gesehen habe. YMMV.

Todd A. Jacobs
quelle
4
Dank CG denke ich, dass "Verwenden Sie es, um schnelle Vorlaufzusammenführungen zu erstellen" der Schlüssel ist. Es gilt nicht für meinen obigen Fall, in dem ich zwei Live-Zweige habe - einen Entwicklungszweig und einen Release-Zweig, aber es scheint sehr gut für temporäre Themenzweige zu gelten, die nur für eine begrenzte Zeitspanne erforderlich sind und dann sein können gelöscht, sobald sie zusammengeführt sind. Danke noch einmal.
Roy Truelove
1
Ich verstehe das, aber die ursprüngliche Frage bleibt. Ich denke, die eigentliche Antwort ist die von @Fabien Quatravaux
IsmailS
4
Nun, Sie müssten den 1.0-Zweig immer noch zwangsweise drücken, nein? Zumindest ist das für mich die ganze Zeit so. Die Fabiens-Methode würde dies verhindern.
Joerx
23

@ CodeGnome ist richtig. Sie sollten den Master nicht auf dem Zweig v1.0 neu gründen, sondern den Zweig v1.0 auf dem Master, da dies den Unterschied ausmacht.

git checkout -b integrate_patches v1.0
git rebase master
git checkout master
git merge integrate_patches

Erstellen Sie einen neuen Zweig, der auf v1.0 verweist, verschieben Sie diesen neuen Zweig über den Master und integrieren Sie dann die neue Version der V1.0-Patches in den Master-Zweig. Sie werden am Ende so etwas wie:

o [master] [integrate_patches] Another patch on v1.0
o A patch on v1.0
o Another change for the next major release
o Working on the next major release
|  o [v1.0] Another path on v1.0
|  o A patch on v1.0
| /
o Time for the release

Diese Art der Verwendung von Rebase wird in der offiziellen Git-Dokumentation empfohlen .

Ich denke, Sie haben Recht git push --force: Sie sollten es nur verwenden, wenn Sie einen Fehler gemacht und etwas gepusht haben, das Sie nicht wollten.

Fabien Quatravaux
quelle
Ich denke, dies ist die beste Antwort für das spezifische Problem im OP. Sie erstellen einen temporären Zusammenführungszweig und bauen ihn erneut auf, führen ihn dann zum Master zusammen und verschieben ihn zum Ursprung. Der temporäre Zweig muss nicht zum Ursprung verschoben werden. Der einzige zusätzliche Rat, den ich geben würde, ist eine Entwicklungs- oder Qa-Verzweigung, in der der zusammengeführte / neu basierte Code qualifiziert werden kann. Nach der Qualifikation würde dieser Code dann nur noch mit dem Master zusammengeführt. Dies ermöglicht ein einfaches Hotfixing, wenn Ihr Qualifizierungsprozess zu lange dauert. Dies ist im Grunde der "Git Flow" -Prozess.
Javid Jamae
Danke Fabien, tolle Antwort. Für diejenigen von uns, die nur die Änderungen integrieren möchten masterund nichts dagegen haben, den Feature-Zweig selbst zusammenzuführen, kann dies getan werden mit:git checkout my-branch; git rebase master; git checkout master; git merge my-branch
Siavas
17

Sie müssen Push erzwingen, wenn Sie die Basis neu festlegen, und Sie haben Ihre Änderungen bereits veröffentlicht, oder?

Ich verwende Rebase für eine ganze Reihe, aber ich veröffentliche entweder auf etwas Privates, bei dem ein Force-Push keine Rolle spielt (z. B. mein eigener Klon auf GitHub als Teil einer Pull-Anfrage), oder ich habe eine Rebase, bevor ich zum ersten Mal Push mache.

Dies ist das Herzstück des Workflows, in dem Sie Rebase verwenden, aber Push nicht viel erzwingen: Veröffentlichen Sie Dinge erst, wenn sie fertig sind, und Rebase nicht nach Push.

Daniel Pittman
quelle
Danke Dan. Können Sie mir mitteilen, wie dies erreicht werden soll? Ist dies nicht ein Szenario, in dem eine Rebase angewendet wird?
Roy Truelove
2
Wenn Sie Ihre gesamte Arbeit auf Themenbereiche beschränken, ist dies ein gutes Szenario für die Neugründung. Sie haben rebaseneue Änderungen in Ihren Themenzweig übernommen, aber wenn Sie die Änderungen in diesem Zweig abgeschlossen haben, kehren Sie mergein den Hauptentwicklungszweig zurück.
Redhotvengeance
1
Das Problem ist, dass Sie den Zweig veröffentlicht haben. Daher müssen Sie einen Push in das Repository erzwingen. Sie müssen eines der beiden aufgeben: Veröffentlichen wie Sie es tun oder neu gründen. Es tut uns leid.
Daniel Pittman
Klingt so, als würde eine Neubasierung in diesem Szenario nicht funktionieren. v1.0 ist kein Themenzweig, sondern ein Release-Zweig, daher wird er niemals sterben und muss veröffentlicht werden.
Roy Truelove
5

Ich denke, es gibt einen guten Anwendungsfall für dieses Rebase-Then-Force-Push-Muster, der nicht auf einen fehlerhaften Push zurückzuführen ist: Sie arbeiten selbst an einem Feature-Zweig von mehreren Standorten (Computern) aus. Ich mache das oft, da ich manchmal im Büro auf meinem Desktop und manchmal von zu Hause / vom Kunden vor Ort auf meinem Laptop arbeite. Ich muss gelegentlich neu aufbauen, um mit dem Hauptzweig Schritt zu halten und / oder Zusammenführungen sauberer zu machen, aber ich muss auch Druck ausüben, wenn ich eine Maschine verlasse, um an einer anderen zu arbeiten (wo ich nur ziehe). Funktioniert wie ein Zauber, solange ich der einzige bin, der an der Niederlassung arbeitet.

8forty
quelle
2
Ich habe den gleichen Workflow (von mehreren Computern / Standorten aus). Nehmen wir also an, Sie arbeiten an einem Themenzweig namens "mytopic". Solange Sie immer einen lokalen Wegwerfzweig (der lediglich ein Zweig von mytopic ist) auf "master" umstellen und diesen dann wieder in mytopic zusammenführen, müssen Sie niemals einen Push erzwingen. OP hat ein etwas anderes Szenario, daher kann in einem solchen Fall ein Kraftstoß erforderlich sein. Ich denke jedoch, dass OP den falschen Weg zurücklegt - wenn er es wie beschrieben tun würde, wäre kein Kraftstoß notwendig.
bwv549
3

Folgendes verwende ich (vorausgesetzt, Ihr Filialname ist foobar ):

git checkout master              # switch to master
git rebase   foobar              # rebase with branch
git merge -s ours origin/master  # do a basic merge -- but this should be empty
git push origin master           # aaand this should work
duftend
quelle
2
Rebasing Master sieht komisch aus.
Emil Vikström
2
gitist nicht ohne Persönlichkeit
redolent
1
git merge -s ours origin/<branch>war das, was es für uns behoben hat
Max
0

tl; dr mit gemeinsam genutzten Zweigen zusammenführen, mit einzelnen Zweigen neu gründen. --force-with-leaseist eine sicherere Alternative zu Gewalt und sollte Ihnen helfen, dieses Git-Nirvana ohne die zerstörerische Natur von Gewalt zu erreichen.

Eine allgemeine Faustregel, die ich für die Workflows verschiedener Teams gesehen habe, ist die Verwendung mergefür gemeinsam genutzte Zweige (dh Master, Master oder Entwicklung) und die Verwendung rebasebei der Arbeit an Ihrem eigenen Feature-Zweig. Hier ist ein typischer Lebenszyklus eines Feature-Zweigs

git checkout master
git checkout -b new-feature
git commit -am "commit new work"
git push -u origin new-feature
# have code reviewed, run CI, etc.,
# meanwhile master has new commits
git checkout master
git pull
git rebase -i master # -i for interactive rebase allows you to squash intermediate commits
git push --force-with-lease
git merge master

Eine einfache englische Version von dem, was wir hier gemacht haben:

  1. Erstellt einen neuen Zweig vom Master
  2. Arbeit am Zweig erledigt und auf Fernbedienung verschoben
  3. vom Meister neu gegründet
  4. Schieben Sie die Arbeit mit auf die Fernbedienung force-with-lease
  5. Mit einem sehr sauberen Git-Protokoll in den Master einbinden, wodurch die Unordnung durch mehrere Zusammenführungen aus unserem gemeinsam genutzten Zweig verringert wird, damit unser Zweig mit dem neuesten Master (gemeinsam genutzter Zweig) "auf dem Laufenden" bleibt.

Der vierte Schritt ist WIRKLICH wichtig und einer der Hauptgründe, warum ich mich für die Verwendung von Rebase ausgesprochen habe. force-with-leaseÜberprüft die Fernbedienung, um festzustellen, ob neue Commits hinzugefügt wurden. Wenn git pushsich herausstellt, dass Sie destruktiv sind, wird es nicht schieben!

Ich hoffe, dies gibt jemandem mehr Vertrauen in die Verwendung von Rebase.

lucasnad27
quelle