wake-up-neo.com

Git Workflow und Rebase vs Merge Fragen

Ich benutze Git jetzt seit ein paar Monaten in einem Projekt mit einem anderen Entwickler. Ich habe mehrere Jahre Erfahrung mit SVN , also bringe ich wohl viel Gepäck in die Beziehung.

Ich habe gehört, dass Git hervorragend zum Verzweigen und Zusammenführen geeignet ist, und bis jetzt sehe ich es einfach nicht. Natürlich ist das Verzweigen denkbar einfach, aber wenn ich versuche zu verschmelzen, geht alles in die Hölle. Nun, ich bin das von SVN gewohnt, aber es scheint mir, dass ich gerade ein unterdurchschnittliches Versionssystem gegen ein anderes getauscht habe.

Mein Partner sagt mir, dass meine Probleme aus meinem Wunsch resultieren, sich wohl oder übel zusammenzufügen, und dass ich in vielen Situationen Rebase anstelle von Merge verwenden sollte. Zum Beispiel ist hier der Workflow, den er festgelegt hat:

clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature
git checkout master
git merge my_new_feature

Erstellen Sie im Wesentlichen einen Feature-Zweig, führen Sie IMMER einen Rebase-Vorgang vom Master zum Zweig durch und führen Sie ihn vom Zweig zurück zum Master zusammen. Wichtig ist, dass die Filiale immer lokal bleibt.

Hier ist der Workflow, mit dem ich begonnen habe

clone remote repository
create my_new_feature branch on remote repository
git checkout -b --track my_new_feature Origin/my_new_feature
..work, commit, Push to Origin/my_new_feature
git merge master (to get some changes that my partner added)
..work, commit, Push to Origin/my_new_feature
git merge master
..finish my_new_feature, Push to Origin/my_new_feature
git checkout master
git merge my_new_feature
delete remote branch
delete local branch

Es gibt zwei wesentliche Unterschiede (glaube ich): Ich verwende Merge immer anstelle von Re-Basing und schiebe meinen Feature-Zweig (und meine Commits für den Feature-Zweig) in das Remote-Repository.

Meine Überlegung für den Remote-Zweig ist, dass ich meine Arbeit während der Arbeit sichern möchte. Unser Repository wird automatisch gesichert und kann wiederhergestellt werden, wenn etwas schief geht. Mein Laptop ist nicht oder nicht so gründlich. Daher hasse ich es, Code auf meinem Laptop zu haben, der nicht woanders gespiegelt wird.

Meine Argumentation für die Zusammenführung anstelle von "rebase" ist, dass "merge" anscheinend Standard ist und "rebase" eine erweiterte Funktion. Mein Bauchgefühl ist, dass das, was ich versuche, kein erweitertes Setup ist, so dass ein Rebase unnötig sein sollte. Ich habe sogar das neue Pragmatic Programming-Buch über Git durchgesehen, und sie befassen sich ausführlich mit Merge und erwähnen kaum Rebase.

Wie auch immer, ich verfolgte meinen Workflow in einem neuen Zweig, und als ich versuchte, ihn wieder zum Master zusammenzuführen, lief alles zur Hölle. Es gab Unmengen von Konflikten mit Dingen, die eigentlich keine Rolle gespielt hätten. Die Konflikte machten für mich einfach keinen Sinn. Ich brauchte einen Tag, um alles zu klären, und schließlich kam es zu einem erzwungenen Push an den Remote-Master, da mein lokaler Master alle Konflikte gelöst hat, aber der Remote-Master war immer noch nicht glücklich.

Was ist der "richtige" Workflow für so etwas? Git soll das Verzweigen und Zusammenführen supereinfach machen, und ich sehe es einfach nicht.

Update 15.04.2011

Dies scheint eine sehr beliebte Frage zu sein, daher dachte ich, ich würde meine zweijährige Erfahrung aktualisieren, seit ich sie zum ersten Mal gestellt habe.

Es stellt sich heraus, dass der ursprüngliche Workflow zumindest in unserem Fall korrekt ist. Mit anderen Worten, das machen wir und es funktioniert:

clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git checkout master
git merge my_new_feature

Tatsächlich ist unser Arbeitsablauf etwas anders, da wir eher Squash-Merges als Raw-Merges durchführen. ( Hinweis: Dies ist umstritten (siehe unten). Auf diese Weise können wir unseren gesamten Feature-Zweig in ein einziges Commit für Master umwandeln. Dann löschen wir unseren Feature-Zweig. Auf diese Weise können wir unsere Commits nach Master logisch strukturieren, auch wenn sie in unseren Filialen etwas chaotisch sind. Das machen wir also:

clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git checkout master
git merge --squash my_new_feature
git commit -m "added my_new_feature"
git branch -D my_new_feature

Squash-Merge-Kontroverse - Wie mehrere Kommentatoren hervorgehoben haben, wirft der Squash-Merge den gesamten Verlauf Ihres Feature-Zweigs weg. Wie der Name schon sagt, werden alle Festschreibungen zu einer einzigen zusammengefasst. Für kleine Features ist dies sinnvoll, da sie zu einem einzigen Paket zusammengefasst werden. Bei größeren Funktionen ist dies wahrscheinlich keine gute Idee, insbesondere wenn Ihre einzelnen Commits bereits atomar sind. Es kommt wirklich auf die persönlichen Vorlieben an.

Github und Bitbucket (andere?) Pull Requests - Für den Fall, dass Sie sich fragen, wie Merge/Rebase mit Pull Requests zusammenhängt, empfehle ich die folgenden Schritte bis Sie bereit sind, wieder zum Master zusammenzuführen. Anstatt manuell mit git zu verschmelzen, akzeptieren Sie einfach die PR. Beachten Sie, dass hierdurch kein Squash-Merge durchgeführt wird (zumindest nicht standardmäßig), aber Non-Squash, Non-Fast-Forward ist die akzeptierte Merge-Konvention in der Pull Request-Community (soweit ich weiß). Im Einzelnen funktioniert es so:

clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git Push # May need to force Push
...submit PR, wait for a review, make any changes requested for the PR
git rebase master
git Push # Will probably need to force Push (-f), due to previous rebases from master
...accept the PR, most likely also deleting the feature branch in the process
git checkout master
git branch -d my_new_feature
git remote Prune Origin

Ich habe Git geliebt und möchte nie wieder zu SVN zurückkehren. Wenn Sie Probleme haben, bleiben Sie einfach dabei und irgendwann sehen Sie das Licht am Ende des Tunnels.

939
Micah

"Konflikte" bedeuten "parallele Entwicklungen gleichen Inhalts". Wenn es also während einer Zusammenführung "zur Hölle" geht, bedeutet dies, dass Sie massive Weiterentwicklungen für denselben Satz von Dateien haben.

Der Grund, warum ein Rebase dann besser ist als ein Merge, ist folgender:

  • sie schreiben Ihren lokalen Commit-Verlauf mit dem des Masters neu (und wenden dann Ihre Arbeit erneut an, um etwaige Konflikte zu lösen).
  • die endgültige Zusammenführung wird sicherlich eine "Schnellvorlauf" sein, da sie den gesamten Commit-Verlauf des Masters sowie nur Ihre Änderungen enthält, die erneut angewendet werden sollen.

Ich bestätige, dass der richtige Workflow in diesem Fall (Weiterentwicklungen für allgemeine Dateigruppen) ist, zuerst rebase und dann merge .

Dies bedeutet jedoch, dass, wenn Sie Ihren lokalen Zweig pushen (aus Sicherungsgründen), dieser Zweig nicht von anderen gezogen (oder zumindest verwendet) werden sollte (da der Festschreibungsverlauf durch die sukzessive Neueinstufung neu geschrieben wird).


Zu diesem Thema (Workflow rebase und dann zusammenführen) erwähnt barraponto in den Kommentaren zwei interessante Beiträge, beide von randyfay.com :

Mit dieser Technik wird Ihre Arbeit wie ein Patch, der mit dem aktuellen HEAD auf dem neuesten Stand ist, immer über dem öffentlichen Zweig angezeigt.

(eine ähnliche Technik existiert für Bazaar )

362
VonC

TL; DR

Ein Git-Rebase-Workflow schützt Sie nicht vor Leuten, die schlecht in der Konfliktlösung sind, oder vor Leuten, die an einen SVN-Workflow gewöhnt sind, wie in Vermeiden von Git-Katastrophen: Eine blutige Geschichte . Dies macht die Konfliktlösung für sie nur mühsamer und macht es schwieriger, sich von einer schlechten Konfliktlösung zu erholen. Verwenden Sie stattdessen diff3, damit es gar nicht erst so schwer ist.


Der Neustart-Workflow ist für die Konfliktlösung nicht besser!

Ich bin sehr pro-rebase für die Bereinigung der Geschichte. Wenn ich jedoch jemals auf einen Konflikt stoße, breche ich sofort den Rebase ab und führe stattdessen einen Merge durch! Es macht mich wirklich fertig, dass Leute einen Rebase-Workflow als einen empfehlen Bessere Alternative zu einem Merge-Workflow zur Konfliktlösung (genau darum ging es in dieser Frage).

Wenn es während eines Merges zur Hölle geht, geht es während eines Rebases zur Hölle und möglicherweise auch noch viel mehr zur Hölle! Hier ist der Grund:

Grund Nr. 1: Lösen Sie Konflikte einmal statt einmal pro Festschreibung

Wenn Sie ein Rebase durchführen, anstatt ein Merge durchzuführen, müssen Sie die Konfliktlösung für denselben Konflikt so oft durchführen, wie Sie ein Rebase durchführen möchten!

Echtes Szenario

Ich verzweige vom Master ab, um eine komplizierte Methode in einem Zweig umzugestalten. Meine Refactoring-Arbeit umfasst insgesamt 15 Commits, während ich daran arbeite, sie zu refactoring und Code-Reviews zu erhalten. Ein Teil meines Refactorings beinhaltet das Korrigieren der gemischten Tabs und Leerzeichen, die vorher im Master vorhanden waren. Dies ist notwendig, aber leider widerspricht es jeder Änderung, die später in master an dieser Methode vorgenommen wird. Sicher genug, während ich an dieser Methode arbeite, nimmt jemand eine einfache, legitime Änderung an derselben Methode im Hauptzweig vor, die mit meinen Änderungen zusammengeführt werden soll.

Wenn es Zeit ist, meinen Zweig wieder mit dem Master zusammenzuführen, habe ich zwei Möglichkeiten:

git merge: Ich bekomme einen Konflikt. Ich sehe die Veränderung, die sie vorgenommen haben, um sie zu meistern und mit (dem Endprodukt) meiner Branche zu verschmelzen. Getan.

git rebase: Ich bekomme einen Konflikt mit meinem ersten Commit. Ich löse den Konflikt und setze die Rebase fort. Ich bekomme einen Konflikt mit meinem zweiten Commit. Ich löse den Konflikt und setze die Rebase fort. Ich bekomme einen Konflikt mit meinem dritten Commit. Ich löse den Konflikt und setze die Rebase fort. Ich bekomme einen Konflikt mit meinem vierten Commit. Ich löse den Konflikt und setze die Rebase fort. Ich bekomme einen Konflikt mit meinem fünften Commit. Ich löse den Konflikt und setze die Rebase fort. Ich bekomme einen Konflikt mit meinem sechsten Commit. Ich löse den Konflikt und setze die Rebase fort. Ich bekomme einen Konflikt mit meinem siebten Commit. Ich löse den Konflikt und setze die Rebase fort. Ich bekomme einen Konflikt mit meinem achten Commit. Ich löse den Konflikt und setze die Rebase fort. Ich bekomme einen Konflikt mit meinem neunten Commit. Ich löse den Konflikt und setze die Rebase fort. Ich bekomme einen Konflikt mit meinem zehnten Commit. Ich löse den Konflikt und setze die Rebase fort. Ich bekomme einen Konflikt mit meinem elften Commit. Ich löse den Konflikt und setze die Rebase fort. Ich habe einen Konflikt mit meinem zwölften Commit. Ich löse den Konflikt und setze die Rebase fort. Ich bekomme einen Konflikt mit meinem dreizehnten Commit. Ich löse den Konflikt und setze die Rebase fort. Ich bekomme einen Konflikt mit meinem vierzehnten Commit. Ich löse den Konflikt und setze die Rebase fort. Ich bekomme einen Konflikt mit meinem fünfzehnten Commit. Ich löse den Konflikt und setze die Rebase fort.

Sie müssen mich veräppeln, wenn dies Ihr bevorzugter Workflow ist. Alles, was es braucht, ist ein Whitespace-Fix, der mit einer am Master vorgenommenen Änderung in Konflikt steht, und jedes Commit wird in Konflikt geraten und muss gelöst werden. Und dies ist ein einfaches Szenario mit nur einem Leerzeichen-Konflikt. Himmel verbieten, dass Sie einen echten Konflikt haben, der größere Codeänderungen zwischen Dateien beinhaltet, und müssen das mehrfach auflösen.

Mit all der zusätzlichen Konfliktlösung, die Sie tun müssen, erhöht sich nur die Wahrscheinlichkeit, dass Sie einen Fehler machen . Aber Fehler sind in Git in Ordnung, da man sie rückgängig machen kann, oder? Außer natürlich ...

Grund 2: Mit Rebase gibt es kein Rückgängigmachen!

Ich denke, wir können uns alle einig sein, dass die Lösung von Konflikten schwierig sein kann und dass einige Leute sehr schlecht darin sind. Es kann sehr fehleranfällig sein, weshalb es so großartig ist, dass es mit git leicht rückgängig gemacht werden kann!

Wenn Sie einen Zweig zusammenführen , erstellt git ein Zusammenführungs-Commit, das verworfen oder geändert werden kann, wenn die Konfliktlösung schlecht verläuft. Selbst wenn Sie das schlechte Merge-Commit bereits auf das öffentliche/autorisierende Repo übertragen haben, können Sie mit git revert die durch das Merge eingeführten Änderungen rückgängig machen und das Merge in einem neuen Merge-Commit korrekt wiederholen.

Wenn Sie einen Zweig rebasieren , sind Sie in dem wahrscheinlichen Fall, dass die Konfliktlösung falsch durchgeführt wird, durcheinander. Jedes Commit enthält jetzt die fehlerhafte Zusammenführung, und Sie können die Neueinstellung nicht einfach wiederholen *. Bestenfalls müssen Sie zurückgehen und jedes der betroffenen Commits ändern. Kein Spaß.

Nach einem Rebase ist es unmöglich festzustellen, was ursprünglich Teil der Commits war und was als Ergebnis einer schlechten Konfliktlösung eingeführt wurde.

* Es kann möglich sein, eine Rebase rückgängig zu machen, wenn Sie die alten Refs aus den internen Protokollen von git auslesen können oder wenn Sie einen dritten Zweig erstellen, der auf das letzte Commit vor dem Rebasing verweist.

Nimm die Hölle aus der Konfliktlösung heraus: benutze diff3

Nehmen Sie diesen Konflikt zum Beispiel:

<<<<<<< HEAD
TextMessage.send(:include_timestamp => true)
=======
EmailMessage.send(:include_timestamp => false)
>>>>>>> feature-branch

Wenn man sich den Konflikt ansieht, ist es unmöglich zu sagen, was sich in jedem Zweig geändert hat oder was seine Absicht war. Dies ist meiner Meinung nach der Hauptgrund, warum die Konfliktlösung verwirrend und schwierig ist.

diff3 zur rettung!

git config --global merge.conflictstyle diff3

Wenn Sie diff3 verwenden, hat jeder neue Konflikt einen dritten Abschnitt, den zusammengeführten gemeinsamen Vorfahren.

<<<<<<< HEAD
TextMessage.send(:include_timestamp => true)
||||||| merged common ancestor
EmailMessage.send(:include_timestamp => true)
=======
EmailMessage.send(:include_timestamp => false)
>>>>>>> feature-branch

Untersuchen Sie zuerst den zusammengeführten gemeinsamen Vorfahren. Vergleichen Sie dann jede Seite, um die Absicht jedes Zweigs zu bestimmen. Sie können sehen, dass HEAD EmailMessage in TextMessage geändert hat. Es ist beabsichtigt, die verwendete Klasse in TextMessage zu ändern und dieselben Parameter zu übergeben. Sie können auch sehen, dass es die Absicht des Feature-Zweigs ist, false anstelle von true für die Option: include_timestamp zu übergeben. Kombinieren Sie die Absicht beider, um diese Änderungen zusammenzuführen:

TextMessage.send(:include_timestamp => false)

Im Allgemeinen:

  1. Vergleichen Sie den gemeinsamen Vorfahren mit jedem Zweig und bestimmen Sie, welcher Zweig die einfachste Änderung aufweist
  2. Wenden Sie diese einfache Änderung auf die Version des Codes des anderen Zweigs an, sodass diese sowohl die einfachere als auch die komplexere Änderung enthält
  3. Entfernen Sie alle anderen Abschnitte des Konfliktcodes als den, in dem Sie die Änderungen gerade zusammengeführt haben

Alternative: Lösung durch manuelles Anwenden der Änderungen der Verzweigung

Schließlich sind einige Konflikte auch mit diff3 schrecklich zu verstehen. Dies geschieht insbesondere dann, wenn diff gemeinsame Zeilen findet, die semantisch nicht gemeinsam sind (z. B. beide Zweige hatten zufällig eine Leerzeile an derselben Stelle!). Beispielsweise ändert ein Zweig den Einzug des Hauptteils einer Klasse oder ordnet ähnliche Methoden neu. In diesen Fällen kann eine bessere Auflösungsstrategie darin bestehen, die Änderung von beiden Seiten der Zusammenführung zu untersuchen und das Diff manuell auf die andere Datei anzuwenden.

Schauen wir uns an, wie wir einen Konflikt in einem Szenario lösen können, in dem Origin/feature1 wo lib/message.rb Konflikte auftreten.

  1. Entscheiden Sie, ob der derzeit ausgecheckte Zweig (HEAD oder --ours) oder der Zweig, den wir zusammenführen (Origin/feature1 oder --theirs), einfacher anzuwenden ist. Wenn Sie diff mit Tripelpunkt (git diff a...b) verwenden, werden die Änderungen angezeigt, die bei b seit der letzten Abweichung von a aufgetreten sind. Mit anderen Worten, vergleichen Sie den gemeinsamen Vorfahren von a und b mit b.

    git diff HEAD...Origin/feature1 -- lib/message.rb # show the change in feature1
    git diff Origin/feature1...HEAD -- lib/message.rb # show the change in our branch
    
  2. Schauen Sie sich die kompliziertere Version der Datei an. Dadurch werden alle Konfliktmarkierungen entfernt und die ausgewählte Seite verwendet.

    git checkout --ours -- lib/message.rb   # if our branch's change is more complicated
    git checkout --theirs -- lib/message.rb # if Origin/feature1's change is more complicated
    
  3. Ziehen Sie nach dem Auschecken der komplizierten Änderung das Diff der einfacheren Änderung nach oben (siehe Schritt 1). Wenden Sie jede Änderung von diesem Diff auf die widersprüchliche Datei an.

374
Edward Anderson

In meinem Workflow baue ich so viel wie möglich neu auf (und ich versuche es oft. Wenn ich nicht zulasse, dass sich die Diskrepanzen ansammeln, wird die Menge und die Schwere der Kollisionen zwischen Zweigen drastisch verringert).

Selbst in einem meist rebase-basierten Workflow ist jedoch Platz für Zusammenführungen.

Wenn Sie sich daran erinnern, dass die Zusammenführung tatsächlich einen Knoten mit zwei übergeordneten Elementen erstellt. Stellen Sie sich nun die folgende Situation vor: Ich habe zwei unabhängige Feature-Brances A und B und möchte nun Dinge auf Feature-Zweig C entwickeln, die sowohl von A als auch von B abhängen, während A und B überprüft werden.

Was ich dann mache, ist folgendes:

  1. Erstellen (und auschecken) Sie Zweig C über A.
  2. Füge es mit B zusammen

Jetzt enthält Zweig C Änderungen von A und B, und ich kann ihn weiterentwickeln. Wenn ich A ändere, rekonstruiere ich das Diagramm der Zweige folgendermaßen:

  1. erstellen Sie den Zweig T auf der neuen Oberseite von A
  2. verschmelze T mit B
  3. rebase C auf T
  4. zweig T löschen

Auf diese Weise kann ich tatsächlich beliebige Diagramme von Zweigen verwalten, aber komplexere Vorgänge als die oben beschriebene Situation sind bereits zu komplex, da es kein automatisches Tool gibt, mit dem die Neugründung durchgeführt werden kann, wenn sich das übergeordnete Element ändert.

31
Alex Gontmakher

Verwenden Sie NICHT git Push Origin --mirror UNTER FAST JEGLICHEN UMSTÄNDEN.

Es wird nicht gefragt, ob Sie sicher sind, dass Sie dies tun möchten, und Sie sollten sicher sein, dass alle Ihre Remote-Zweige gelöscht werden, die sich nicht in Ihrer lokalen Box befinden.

http://Twitter.com/dysinger/status/1273652486

21
Scott Brown

Ich habe eine Frage, nachdem ich Ihre Erklärung gelesen habe: Könnte es sein, dass Sie nie eine gemacht haben?

git checkout master
git pull Origin
git checkout my_new_feature

bevor Sie den "Git Rebase/Merge Master" in Ihrem Feature-Zweig ausführen?

Weil Ihr Hauptzweig nicht automatisch aus dem Repository Ihres Freundes aktualisiert wird. Das musst du mit dem git pull Origin machen. Das heißt Vielleicht würden Sie immer von einer sich nie ändernden lokalen Hauptniederlassung zurückgreifen? Und dann kommt die Push-Zeit, Sie pushen in ein Repository, das (lokale) Commits hat, die Sie nie gesehen haben, und daher schlägt der Push fehl.

14
knweiss

In Ihrer Situation denke ich, dass Ihr Partner richtig ist. Das Schöne am Neu-Basieren ist, dass Ihre Änderungen für den Außenstehenden so aussehen, als ob sie alle in einer sauberen Reihenfolge von alleine geschehen wären. Das heisst

  • ihre Änderungen sind sehr einfach zu überprüfen
  • sie können weiterhin nette, kleine Commits erstellen und dennoch Sätze dieser Commits gleichzeitig veröffentlichen (durch Zusammenführen mit master)
  • wenn Sie sich die öffentliche Hauptniederlassung ansehen, werden Sie verschiedene Festschreibungsreihen für verschiedene Funktionen von verschiedenen Entwicklern sehen, aber sie werden nicht alle vermischt

Sie können Ihren privaten Entwicklungszweig weiterhin für Sicherungszwecke in das Remote-Repository verschieben, aber andere sollten diesen Zweig nicht als "öffentlichen" Zweig behandeln, da Sie einen Neu-Basing durchführen. Übrigens, ein einfacher Befehl dafür ist git Push --mirror Origin.

Der Artikel Packaging Software using Git macht einen ziemlich guten Job und erklärt die Kompromisse zwischen Zusammenführen und Neu-Basieren. Es ist ein etwas anderer Kontext, aber die Prinzipien sind die gleichen - im Grunde kommt es darauf an, ob Ihre Filialen öffentlich oder privat sind und wie Sie sie in die Hauptleitung integrieren möchten.

13
Pat Notz

Wie auch immer, ich verfolgte meinen Workflow in einem neuen Zweig, und als ich versuchte, ihn wieder zum Master zusammenzuführen, lief alles zur Hölle. Es gab Unmengen von Konflikten mit Dingen, die eigentlich keine Rolle gespielt hätten. Die Konflikte machten für mich einfach keinen Sinn. Ich brauchte einen Tag, um alles zu klären, und schließlich kam es zu einem erzwungenen Push an den Remote-Master, da mein lokaler Master alle Konflikte gelöst hat, aber der Remote-Master war immer noch nicht glücklich.

Sie sollten weder in den Workflows Ihres Partners noch in den von Ihnen vorgeschlagenen Workflows auf Konflikte gestoßen sein, die keinen Sinn ergaben. Selbst wenn Sie den vorgeschlagenen Arbeitsabläufen folgen, sollte nach der Lösung kein "erzwungener" Push erforderlich sein. Es deutet darauf hin, dass Sie den Zweig, auf den Sie pushen, nicht tatsächlich zusammengeführt haben, sondern einen Zweig pushen mussten, der nicht von der entfernten Spitze abstammt.

Ich denke, Sie müssen genau hinschauen, was passiert ist. Könnte jemand anderes (absichtlich oder nicht) den Remote-Master-Zweig zwischen Ihrer Erstellung des lokalen Zweigs und dem Punkt zurückgespult haben, an dem Sie versucht haben, ihn wieder mit dem lokalen Zweig zusammenzuführen?

Im Vergleich zu vielen anderen Versionskontrollsystemen habe ich festgestellt, dass die Verwendung von Git weniger Kampf gegen das Tool erfordert und es Ihnen ermöglicht, sich mit den Problemen zu befassen, die für Ihre Quelldatenströme von grundlegender Bedeutung sind. Git führt keine Magie aus, daher führen widersprüchliche Änderungen zu Konflikten, aber es sollte das Schreiben durch die Verfolgung der Commit-Abstammung vereinfachen.

12
CB Bailey

Nach meinen Beobachtungen werden die Zweige durch Git-Merge auch nach dem Zusammenführen getrennt, während durch Rebase-Merge diese zu einem einzigen Zweig zusammengefasst werden. Letzteres ist viel übersichtlicher, während es im ersten Fall auch nach dem Zusammenführen einfacher ist, herauszufinden, welche Commits zu welchem ​​Zweig gehören.

7
Pepe

"Auch wenn Sie ein einzelner Entwickler mit nur wenigen Niederlassungen sind, lohnt es sich, sich daran zu gewöhnen, Rebase zu verwenden und ordnungsgemäß zusammenzuführen. Das grundlegende Arbeitsmuster sieht folgendermaßen aus:

  • Erstellen Sie eine neue Verzweigung B aus der vorhandenen Verzweigung A

  • Änderungen in Zweig B hinzufügen/festschreiben

  • Aktualisierungen von Zweigstelle A neu starten

  • Änderungen aus Zweig B in Zweig A zusammenführen "

https://www.atlassian.com/git/tutorials/merging-vs-rebasing/

6
Rakka Rage

Mit Git gibt es keinen "richtigen" Workflow. Verwenden Sie alles, was Ihr Boot schwimmt. Wenn jedoch beim Zusammenführen von Filialen ständig Konflikte auftreten, sollten Sie Ihre Bemühungen möglicherweise besser mit den anderen Entwicklern abstimmen. Klingt so, als würden Sie beide weiterhin dieselben Dateien bearbeiten. Achten Sie auch auf Whitespace- und Subversion-Schlüsselwörter (z. B. "$ Id $" und andere).

2
Bombe