Wann sollte ich git pull --rebase verwenden?


806

Ich kenne einige Leute, die git pull --rebasestandardmäßig verwenden, und andere, die darauf bestehen, es niemals zu verwenden. Ich glaube, ich verstehe den Unterschied zwischen Zusammenführen und Umbasieren, aber ich versuche dies in den Kontext von zu stellen git pull. Geht es nur darum, nicht viele Merge-Commit-Nachrichten zu sehen, oder gibt es andere Probleme?


1
Quelle für Leute, die von Git Pull - Rebase raten? Rebase oder Git Rebase ist eine separate Aktivität von Git Pull - Rebase!
przemo_li

Antworten:


584

Sie sollten verwenden, git pull --rebasewenn

  • Ihre Änderungen verdienen keinen separaten Zweig

In der Tat - warum dann nicht? Es ist klarer und legt Ihren Commits keine logische Gruppierung auf.


Ok, ich nehme an, es bedarf einer Klarstellung. Wie Sie wahrscheinlich wissen, werden Sie in Git dazu ermutigt, zu verzweigen und zusammenzuführen. Ihr lokaler Zweig, in den Sie Änderungen ziehen, und Ihr Remote-Zweig sind eigentlich verschiedene Zweige und es git pullgeht darum, sie zusammenzuführen. Es ist vernünftig, da Sie nicht sehr oft pushen und normalerweise eine Reihe von Änderungen sammeln, bevor sie eine abgeschlossene Funktion darstellen.

Manchmal - aus welchem ​​Grund auch immer - denken Sie jedoch, dass es tatsächlich besser wäre, wenn diese beiden - entfernte und lokale - eine Niederlassung wären . Wie in SVN. Hier git pull --rebasekommt das Spiel ins Spiel. Sie werden nicht mehr zusammengeführt - Sie werden tatsächlich über dem Remote-Zweig festgeschrieben . Darum geht es eigentlich.

Ob es gefährlich ist oder nicht, ist die Frage, ob Sie lokale und entfernte Niederlassungen als eine untrennbare Sache behandeln. Manchmal ist es vernünftig (wenn Ihre Änderungen klein sind oder wenn Sie sich am Anfang einer robusten Entwicklung befinden, wenn wichtige Änderungen durch kleine Commits vorgenommen werden). Manchmal ist es nicht so (wenn Sie normalerweise einen anderen Zweig erstellen würden, aber dafür zu faul waren). Aber das ist eine andere Frage.


17
Ich denke, es ist nützlich, wenn Sie am selben Zweig arbeiten, aber Sie können Ihre Workstation ändern. Ich neige dazu, meine Änderungen von einer Workstation aus zu übernehmen und zu übertragen, dann die Rebase in die andere zu ziehen und weiter an demselben Zweig zu arbeiten.
Pablo Pazos

11
Es ist eine nützliche bewährte Methode, Git git config --global pull.rebase preserve so einzurichten, dass beim Ziehen mit automatisch eine Neubasis erstellt wird .
Colin D Bennett

2
Ich bin nicht der Meinung, dass Sie pull --rebase nur verwenden sollten, wenn Sie an einem Zweig arbeiten. Sie sollten es die ganze Zeit verwenden, es sei denn, dies ist aufgrund anderer Umstände unmöglich.
Tomáš Fejfar

@P Shved ... 'Manchmal - aus welchem ​​Grund auch immer - denken Sie jedoch, dass es tatsächlich besser wäre, wenn diese beiden - Remote und Local - ein Zweig wären' ... kann dies getan werden? Mein Verständnis ist In einer lokalen Umgebung kann ich meinen Zweig und einen Remote-Zweigspiegel als Ursprung / Master haben. Können Sie hier bitte Eingaben machen?
Mandroid

736

Ich möchte eine andere Perspektive geben, was "git pull --rebase" eigentlich bedeutet, weil es manchmal verloren zu gehen scheint.

Wenn Sie jemals Subversion (oder CVS) verwendet haben, sind Sie möglicherweise an das Verhalten von "svn update" gewöhnt. Wenn Sie Änderungen festschreiben müssen und die Festschreibung fehlschlägt, weil Änderungen vorgelagert wurden, "svn update". Bei der Subversion werden vorgelagerte Änderungen mit Ihren Änderungen zusammengeführt, was möglicherweise zu Konflikten führt.

Was Subversion gerade getan hat, war im Wesentlichen "pull - rebase". Das Umformulieren Ihrer lokalen Änderungen in Bezug auf die neuere Version ist der "Neuausrichtung" -Teil davon. Wenn Sie vor dem fehlgeschlagenen Festschreibungsversuch "svn diff" ausgeführt und anschließend das resultierende Diff mit der Ausgabe von "svn diff" verglichen haben, ist der Unterschied zwischen den beiden Diffs der Vorgang, den die Neubasierungsoperation ausgeführt hat.

Der Hauptunterschied zwischen Git und Subversion besteht in diesem Fall darin, dass in Subversion "Ihre" Änderungen nur als nicht festgeschriebene Änderungen in Ihrer Arbeitskopie vorhanden sind, während Sie in Git tatsächlich lokale Commits haben. Mit anderen Worten, in Git haben Sie die Geschichte gegabelt; Ihre Geschichte und die vorgelagerte Geschichte sind auseinander gegangen, aber Sie haben einen gemeinsamen Vorfahren.

Meiner Meinung nach ist im Normalfall einfach Ihre lokale Niederlassung mit reflektierenden das Upstream - Zweig und es kontinuierliche Entwicklung zu tun, das Richtige zu tun ist immer „--rebase“, denn das ist , was Sie eigentlich semantisch tun . Sie und andere hacken die beabsichtigte lineare Geschichte eines Zweigs ab. Die Tatsache, dass jemand anderes vor Ihrem versuchten Push etwas Druck gemacht hat, ist irrelevant, und es scheint kontraproduktiv zu sein, wenn jeder solche Unfall des Timings zu Zusammenführungen in der Geschichte führt.

Wenn Sie tatsächlich das Bedürfnis haben, aus irgendeinem Grund eine Branche zu sein, ist dies meiner Meinung nach ein anderes Anliegen. Aber wenn Sie nicht den spezifischen und aktiven Wunsch haben, Ihre Änderungen in Form einer Zusammenführung darzustellen, sollte das Standardverhalten meiner Meinung nach "git pull --rebase" sein.

Bitte berücksichtigen Sie andere Personen, die die Geschichte Ihres Projekts beobachten und verstehen müssen. Möchten Sie, dass die Geschichte überall mit Hunderten von Zusammenführungen übersät ist, oder möchten Sie nur die wenigen ausgewählten Zusammenführungen, die echte Zusammenführungen von absichtlich unterschiedlichen Entwicklungsbemühungen darstellen?


18
@MarceloCantos Um es klar auszudrücken, ich sage nicht, dass git (das Tool) standardmäßig neu basiert werden sollte. Das wäre gefährlich, da eine Rebase die Geschichte im Wesentlichen zerstört. Ich sage, in Bezug auf den Workflow sollte "git pull --rebase" das Standardverhalten des Benutzers sein, wenn Sie nicht beabsichtigen, zu verzweigen und nur einen Zweig zu hacken, an dem andere Leute ebenfalls arbeiten.
Scode

1
Wollen Sie damit sagen, dass man nicht sollte git config --global branch.autosetupmerge always?
Marcelo Cantos

9
@MarceloCantos Nein, bin ich nicht;) Persönlich würde ich autosetupmerge als Standard von true belassen (wenn ich zwischen anderen Zweigen als der lokalen <-> Fernbedienung zurück und viertens verschmelze, möchte ich, dass es explizit ist). Ich sage nur, dass ich als Mensch "git pull --rebase" immer als Teil meines normalen Workflows "Neueste im Hauptzweig greifen" verwende, weil ich niemals ein Zusammenführungs-Commit erstellen möchte, es sei denn, ich verzweige explizit.
Scode

9
+1 @scode. Nach vielen schmerzhaften Stunden der Auseinandersetzung mit der Rebase / Merge-Frage ist hier endlich eine Antwort, die es nagelt.
AgileYogi

10
Diese Antwort ist nur ein Versuch, Benutzer nicht verteilter Versionskontrollsysteme an Git anzupassen, anstatt ihnen die Möglichkeit zu geben, die Vorteile geeigneter Zweige richtig zu verstehen.
Alexey Zimarev

211

Vielleicht lässt sich das am besten anhand eines Beispiels erklären:

  1. Alice erstellt den Themenzweig A und arbeitet daran
  2. Bob erstellt einen nicht verwandten Themenzweig B und arbeitet daran
  3. Alice tut es git checkout master && git pull. Der Master ist bereits auf dem neuesten Stand.
  4. Bob tut es git checkout master && git pull. Der Master ist bereits auf dem neuesten Stand.
  5. Alice tut es git merge topic-branch-A
  6. Bob tut es git merge topic-branch-B
  7. Bob tut es git push origin mastervor Alice
  8. Alice tut dies git push origin master, was abgelehnt wird, weil es sich nicht um eine Schnellvorlaufzusammenführung handelt.
  9. Alice schaut auf das Ursprungs- / Masterprotokoll und stellt fest, dass das Commit nichts mit ihrem zu tun hat.
  10. Alice tut es git pull --rebase origin master
  11. Alices Merge-Commit wird abgewickelt, Bobs Commit wird gezogen und Alices Commit wird nach Bobs Commit angewendet.
  12. Alice tut es git push origin masterund alle sind froh, dass sie kein nutzloses Zusammenführungs-Commit lesen müssen, wenn sie sich in Zukunft die Protokolle ansehen.

Beachten Sie, dass der spezifische Zweig, in den zusammengeführt wird, für das Beispiel irrelevant ist. Der Master in diesem Beispiel kann genauso gut ein Release-Zweig oder ein Dev-Zweig sein. Der entscheidende Punkt ist, dass Alice & Bob gleichzeitig ihre lokalen Zweige zu einem gemeinsam genutzten Remote-Zweig zusammenführen.


2
Nett. Ich neige dazu, explizit zu sein git co master && git pull; git checkout topic-branch-A; git rebase master; git checkout master; git merge topic-branch-A; git push origin masterund zu wiederholen, wenn der Vorstoß eines anderen zum Meister vor meinem stattgefunden hat. Obwohl ich die prägnanten Vorteile in Ihrem Rezept sehen kann.
HankCa

Schöne Erklärung @Cody Poll
Rajanikanta Pradhan

148

Ich denke, Sie sollten verwenden, git pull --rebasewenn Sie mit anderen in derselben Branche zusammenarbeiten. Sie befinden sich in Ihrem Arbeitszyklus → Festschreiben → Arbeiten → Festschreiben, und wenn Sie sich entscheiden, Ihre Arbeit zu pushen, wird Ihr Push abgelehnt, da in demselben Zweig parallel gearbeitet wurde. An dieser Stelle mache ich immer eine pull --rebase. Ich verwende keinen Squash (um Commits zu reduzieren), aber ich base neu, um die zusätzlichen Merge-Commits zu vermeiden.

Mit zunehmendem Git-Wissen beschäftigen Sie sich viel mehr mit der Geschichte als mit anderen Versionskontrollsystemen, die ich verwendet habe. Wenn Sie eine Menge kleiner Zusammenführungs-Commits haben, verlieren Sie leicht den Fokus auf das Gesamtbild, das in Ihrer Geschichte passiert.

Dies ist tatsächlich das einzige Mal, dass ich eine Neubasierung durchführe (*), und der Rest meines Workflows basiert auf Zusammenführung. Aber solange Ihre häufigsten Committer dies tun, sieht die Geschichte am Ende viel besser aus.

(*) Während ich einen Git-Kurs unterrichtete, wurde ich von einem Studenten verhaftet, da ich unter bestimmten Umständen auch befürwortete, Feature-Zweige neu zu gründen. Und er hatte diese Antwort gelesen;) Eine solche Umbasierung ist ebenfalls möglich, muss aber immer nach einem vorher festgelegten / vereinbarten System erfolgen und sollte daher nicht "immer" angewendet werden. Und zu dieser Zeit mache ich normalerweise auch nicht pull --rebase, worum es bei der Frage geht;)


2
Sicherlich kann man ein Skript schreiben, um die Zusammenführungs-Commits aus dem Protokoll zu verbergen
hasen

3
Zusammenführungen können auch Unterschiede enthalten, was bedeutet, dass es nicht ganz trivial ist
krosenvold

9
@hasen j Ja, aber der INHALT dieser Zusammenschlüsse kann von Bedeutung sein
krosenvold

Diese Antwort ist vage und einfühlsam im Vergleich zu der gewählten Antwort: Was meinst du genau mit "gleicher Zweig"? Es gibt einige gute Punkte, die jedoch nicht in der gewählten Antwort enthalten sind.
iwein

1
Die Unbestimmtheit um "Zweig" ist ziemlich beabsichtigt, da es so viele Möglichkeiten gibt, Refs zu verwenden; "Arbeitslinie" ist nur eine Option.
Krosenvold

49

Ich glaube nicht, dass es jemals einen Grund gibt, dies nicht zu verwenden. pull --rebaseIch habe Git speziell Code hinzugefügt, damit mein git pullBefehl immer gegen Upstream-Commits zurückgesetzt werden kann.

Wenn Sie durch die Geschichte schauen, ist es einfach nie interessant zu wissen, wann der Typ, der an der Funktion arbeitet, aufgehört hat, sich zu synchronisieren. Es könnte für den Kerl / die Frau nützlich sein, während er / sie es tut, aber dafür reflogist es da. Es fügt nur Lärm für alle anderen hinzu.


2
"Wenn man durch die Geschichte blickt, ist es einfach nie interessant zu wissen, wann der Typ, der an der Funktion arbeitet, aufgehört hat, sich zu synchronisieren." / Aber heißt das nicht, dass diese Zwischen-Commits wahrscheinlich fehlerhafte Builds sind?
Eglasius

10
Ja, und sie sind auch kein "ganzer Staat". Deshalb wollen wir sie nicht. Ich möchte wissen, was er wollte, nicht wie er dorthin gekommen ist.
Dustin

4
Wenn pull --rebaseimmer verwendet werden sollte, warum nicht pullstandardmäßig?
Straya

2
Ich fürchte, Sie müssen sich eine eigene Meinung bilden. Ich habe verschiedene Dinge in mir .gitconfig, damit einige der Optionen das Richtige tun. Ich denke, Git Rebase macht standardmäßig das Falsche, ebenso wie Git Tag usw. Wenn Sie nicht einverstanden sind, müssen Sie Ihre Meinung nicht begründen.
Dustin

8
Das scheint ein guter Rat zu sein, wenn Sie von "Upstream" ziehen, sagen wir von master, und wenn der Zweig, in den Sie ziehen, (noch) nicht an die Börse gegangen ist. Wenn Sie andererseits von einem Feature-Zweig in masterden umgekehrten ziehen, ist es eher umgekehrt: Es gibt nie einen Grund, ihn zu verwenden --rebase, oder? Dies könnte der Grund sein, warum dies nicht die Standardeinstellung ist. Ich fand, dass bei Rebases Änderungen von der Spitze der Hierarchie nach unten und bei Zusammenführungen nach oben zurückfließen sollten. derekgourlay.com/blog/git-when-to-merge-vs-when-to-rebase
jolvi

38

Denk dran:

  • pull = fetch + merge
  • pull --rebase = fetch + rebase

Wählen Sie also die Art und Weise, wie Sie mit Ihrer Branche umgehen möchten.

Du solltest besser den Unterschied zwischen Merge und Rebase kennen :)


9

Ich denke, es läuft auf eine persönliche Präferenz hinaus.

Möchten Sie Ihre dummen Fehler verbergen, bevor Sie Ihre Änderungen vornehmen? Wenn ja, git pull --rebaseist perfekt. Sie können Ihre Commits später auf einige (oder einen) Commits reduzieren. Wenn Sie in Ihrer (nicht gepushen) Historie Zusammenführungen haben, ist es nicht so einfach, eine git rebasespätere durchzuführen .

Es macht mir persönlich nichts aus, all meine dummen Fehler zu veröffentlichen, daher neige ich dazu, zusammenzuführen, anstatt sie neu zu gründen.


8
Hinweis für alle, die diese Frage sehen: Diese Antwort ist für die Frage "Wann sollte ich Git Pull - Rebase verwenden?" Völlig irrelevant.
Therealklanni

3
@therealklanni Ich habe die Antwort bearbeitet, damit klarer wird, wie relevant sie für die Frage ist (hoffentlich ohne die Absicht zu zerstören).
Paŭlo Ebermann

Das Teilen eines schmutzigen und unstrukturierten Arbeitsprotokolls ist kein ehrliches Unterfangen, sondern nur Faulheit. Sie verschwenden die Zeit der Menschen, indem sie sie dazu bringen, Sie durch Ihr Kaninchenloch der Entwicklung und des Debuggens zu jagen. Gib ihnen das Ergebnis, nicht das Geschwafel.
krystah

8

git pull --rebaseMöglicherweise wird das Umschreiben eines Verlaufs vor einem Mitarbeiter ausgeblendet git push --force. Ich empfehle die Verwendung git pull --rebase nur, wenn Sie wissen, dass Sie vergessen haben, Ihre Commits zu pushen, bevor jemand anderes dasselbe tut.

Wenn Sie nichts festgelegt haben, aber Ihr Arbeitsbereich nicht sauber ist, kurz git stashvor git pull. Auf diese Weise schreiben Sie Ihren Verlauf nicht stillschweigend neu (wodurch ein Teil Ihrer Arbeit stillschweigend fallen gelassen werden könnte).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.