Arbeiten an einem Zweig, dessen Abhängigkeit von einem anderen Zweig überprüft wird

65

Wie hilft git mit dem folgenden Szenario umzugehen:

Ich habe eine Aufgabe in 2 Teile unterteilt: Backend-Aufgabe und Frontend-Aufgabe. Ich mache eine Pull-Anfrage, um die Backend-Änderungen zusammenzuführen und zu warten, bis sie zusammengeführt wurden (und um Feedback zu erhalten). Während des Wartens kann ich nicht wirklich an den Änderungen im Frontend arbeiten, da dies von den Änderungen im Backend abhängt und diese im Master-Zweig noch nicht verfügbar sind.

Was ist der beste Weg, um Änderungen in den Frontend-Änderungszweig aus dem Backend-Änderungszweig zu übernehmen, während dieser noch geprüft wird?

sul4bh
quelle
14
In der Regel sollten die Schnittstellen des Back-End-Projekts klar definiert sein. Wenn Sie Ihre Front-End-Implementierung starten, sollte es Sie nicht stören, wenn die Back-End-Logik weiterhin überprüft wird, da Sie ein Mock-Up verwenden können.
Herr Derb
17
@HerrDerb Oh süßes Sommerkind ...
gardenhead
4
Warum können Sie es nicht gegen Ihren noch nicht überprüften Backend-Code schreiben?
user253751
Verfügt Ihr Team über eine vereinbarte Technik, um mit dieser Situation umzugehen? Wenn nicht, sollten Sie sich vielleicht auf so etwas einigen, da es eine ziemlich häufige Situation ist.
Radu Murzea
Da ist gar nichts. Das ist der Grund, warum ich diese Frage gestellt habe. Ich habe sehr gute Vorschläge bekommen. Ich werde die Vorschläge ausprobieren und sehen, wie sie für mich funktionieren.
sul4bh

Antworten:

42

Ich habe dieses Problem auch manchmal. Git ist sehr flexibel. Hier ist eine Möglichkeit, wie Sie es tun können.

Ihre erste Filiale featureAsteht zur Überprüfung bereit.

Ihr zweiter Zweig featureBbefindet sich in der Entwicklung und hängt vom Code im featureAZweig ab.

Fügen Sie den featureAZweig in den featureBZweig ein.

Wenn Sie Änderungen an der featureAVerzweigung vornehmen, sollten Sie featureAdie featureBVerzweigung erneut in der Verzweigung zusammenführen, um die Änderungen zu übernehmen.

Sie sollten auch sicherstellen featureA, dass Sie zuerst featureBin den Haupt-Trunk einbinden featureA. Andernfalls werden Sie versehentlich auch einbinden , wenn Sie in den Haupt-Trunk einbinden . Sobald featureAes in den Hauptstamm übergeht, können Sie den featureAAst loswerden, da dies featureBjetzt nur noch vom Hauptstamm abhängt.

Ich bevorzuge es, wenn meine Feature-Zweige nicht voneinander abhängig sind, aber manchmal sind sie es und du musst damit rollen.

Matt
quelle
Das macht Sinn. Ermöglicht dies, das Zusammenführen featureAauf rückgängig zu machen, featureBfalls dies erforderlich sein sollte?
sul4bh
8
Es gibt keine Operation zum Rückgängigmachen, aber wie bei @ 9000 erwähnt, können Sie einen neuen Zweig erstellen und die gewünschten Commits auswählen featureA, wenn Sie von vorne beginnen müssen. Es ist gut, Git-Zweige als Wegwerfartikel zu betrachten. Sie sind billig und einfach, Sie können immer eine neue Niederlassung machen. Sie können sogar einen Testzweig von Ihrem featureBZweig aus erstellen, wenn Sie mit etwas spielen möchten, bei dem Sie sich nicht sicher sind, und ihn dann verschrotten, wenn er nicht funktioniert hat, oder ihn in Ihrem featureBZweig wieder zusammenführen, wenn dies der Fall ist.
Matt
9
Durch das Zusammenführen entsteht ein Durcheinander, das nur schwer (nicht unmöglich) rückgängig zu machen ist. Ich würde Cherry-Pick oder Rebase (dh: Cherry-Pick alles in FeatureA an der Basis von FeatureB). Siehe die Antwort von 9000.
Pierre.Sassoulas
1
Dies schafft eine komplexe Geschichte, die für viele Jahre ein Problem sein wird, wenn jemand verstehen will, welcher Code für FeatureA und FeatureB geändert wurde
Ian,
2
Wenn FeatureA aktualisiert wird, sollte FeatureB neu basieren und nicht zusammengeführt werden
Lyndon White
40

Warte einen Moment, überspringe das Zusammenführen

Für diesen Ansatz haben Sie nicht möchten , dass Ihr fusionieren feature_ain feature_bwiederholt.

Das Zurücksetzen wurde in anderen Antworten erwähnt, aber nur, um Dinge darauf zurückzusetzen master. Was Sie in Ihrem Fall tun möchten, ist:

  • Starten Sie feature_bvon feature_a, dh:

    git checkout feature_a
    git checkout -b feature_b
    
  • Wann immer sich etwas feature_aändert, während es darauf wartet, zusammengeführt zu werden master, stützen feature_b Sie sich darauf:

    ... commit something onto feature_a ...
    git checkout feature_b
    git rebase feature_a
    
  • Sobald feature_aes in zusammengeführt wurde master, holen Sie sich einfach das neue masterund legen feature_aes ein letztes Mal neu auf:

    git checkout master
    git pull origin master
    git checkout feature_b
    git rebase --onto master feature_a feature_b
    

    Diese letzte Neuformulierung setzt alle Commits, die von dem feature_aCommit (das jetzt irrelevant ist, da es in das Commit eingebunden wurde) abhängen, masterdirekt auf master. Ihr feature_bist jetzt ein einfacher Standardzweig, von dem aus Sie direkt fortfahren master.

BEARBEITEN: Inspiriert von den Kommentaren, ein kleiner Hinweis: Wenn Sie Änderungen vornehmen müssen, die sich auf beide Funktionen feature_aauswirken , stellen Sie sicher, dass Sie die Änderungen vornehmen (und anschließend wie gezeigt erneut ausführen). Machen Sie es nicht in zwei verschiedenen Commits in beiden Zweigen, auch wenn es verlockend sein mag. Wie feature_aes Teil der Geschichte von feature_bist, wird es später möglicherweise zu Konflikten oder "Auferweckungen" von unerwünschtem Code führen, wenn die einzelne Änderung in zwei verschiedenen Commits semantisch falsch ist.

AnoE
quelle
2
Bei mehrmaligem Rebasing feature_akann es später zu Problemen kommen, wenn feature_adas Rebasing in der Zwischenzeit selbst durchgeführt wurde. Als Ergebnis der Ausführung git checkout feature_b; git rebase feature_akönnen Konflikte oder lustige Commits auftreten, die Commits enthalten, die neue Änderungen von rückgängig machen feature_a. Dies ist normalerweise lösbar, indem --interactiveCommits aus der alten Version des anderen Zweigs verwendet und übersprungen werden (das musste ich in letzter Zeit mehrmals tun).
Maaartinus
@maaartinus, danke für das Heads-up, ich bin selbst nicht auf solche Probleme gestoßen. Wie rebaseviel mehr einzelne Schritte als ein einfacher merge, gibt es sicherlich eine deutlich höhere Wahrscheinlichkeit, dass Konflikte entstehen; Auf der anderen Seite mergewäre das in diesem Fall nur semantisch völlig falsch.
AnoE
Ich denke, mergehätte ähnliche oder schlimmere Probleme (ein Konflikt ist nicht so schlimm wie eine ungewollte Veränderung). Ich betrachte einen Zweig als eine Abfolge von gewünschten Änderungen, denen viele nicht zusammenhängende Änderungen (die logischerweise zu einem anderen Zweig gehören) vorangehen . Wenn ich wiederholt mit demselben Zweig rebasiere, entferne ich immer die nicht verbundenen Änderungen, da ich weiß, dass sie sowieso eingehen werden (möglicherweise in einer aktualisierten Form) und es funktioniert.
Maaartinus
1
@maaartinus, ich habe ein kleines Addendum dazu hinzugefügt (um konsequent Änderungen vorzunehmen, die nur im Basiszweig in beide Zweige gehen müssen, nicht in zwei verschiedenen Commits).
AnoE
Schöne Technik. So mache ich es auch immer. git rebase --ontoFTW: D
Radu Murzea
29

Sie haben bereits einen Zweig, von dem jeder Feature-Zweig abhängt und der sich ständig ändert. Es heißt master.

Die typische Methode, mit der ein Feature-Zweig synchron masterbleibt, besteht darin, den Überblick zu behalten . Bei masterÄnderungen befinden Sie sich normalerweise git fetch origin master:master && git rebase masterim Arbeitsverzeichnis Ihrer Filiale.

Mit einem anderen Feature-Zweig können Sie dasselbe tun: Sie können ihn weiterhin abrufen und darauf aufbauen.

Wenn Sie aus irgendeinem Grund Ihre Änderungen in einen anderen Zweig verschieben müssen, können Sie Ihre Commits auswählen , die niemals mit den Commits anderer Zweige gemischt werden.

9000
quelle
Aber ich denke, das Szenario ist, dass Feature-B den Code benötigt, der sich in Feature-A befindet. Eine Verzweigung vom Master wird nicht sehr hilfreich sein. Wo soll ich anfangen? Sollte ich von Feature-a verzweigen und diese synchron halten, bis Feature-a wieder in Master integriert ist, und dann von Master zu Feature-b zurückkehren?
Sinaesthetic
@Sinaesthetic: Sie können natürlich Basis feature-bauf feature-a, und eine Fütterungsmaterial von Zeit zu Zeit tun , wie feature-averändert sich . Dies ist eine typische Methode, um große Änderungen sichtbar zu machen: part-ATeilen Sie sie in (basierend auf master), part-B(basierend auf part-A) und bei Bedarf in weitere auf. Stellen Sie dann für jedes Teil eine Pull-Anfrage, und die Prüfer können sich leichter kleinere, logisch gruppierte Teile ansehen.
9000
Ist es von Bedeutung, wenn ich Teil-B mit Teil-A gegen Teil-B mit Master in Bezug auf die PR ablehne? Ich möchte nur sicherstellen, dass meine Änderungen nicht Teil-A-Änderungen als Änderungen in Teil-B anzeigen. Wie wird sich das auf die PR von Teil B auswirken, wenn ich eine Fusion mit einer Rebase durchführe? Jedes Mal, wenn ich denke, dass ich die Auswirkungen verstehe, erhalte ich ein anderes Ergebnis lol
Sinaesthetic
5

In diesem Fall, in dem die Frontend-Task eine kritische Abhängigkeit vom Backend-Code aufweist und Sie die Arbeit am Frontend beginnen möchten, bevor das Backend fertiggestellt und auf dem Master akzeptiert wurde, starte ich die Frontend-Task einfach als Feature-Zweig, der von der stammt Backend-Verzweigung, anstatt das Frontend auf Master zu verzweigen.

Ein Feature-Zweig, der lange genug lebt, muss gelegentlich in Änderungen vom Master zusammengeführt werden (um sicherzustellen, dass Sie alle Zusammenführungen oder semantischen Konflikte als Teil der Entwicklungsarbeit am Feature-Zweig und nicht als Teil der "Überprüfung, qa, Zusammenführung" miteinander in Einklang bringen. Prozess zu meistern). Wenn Sie dies in Ihrem Front-End-Zweig tun und die Back-End-Arbeit als Master akzeptiert wurde, erhalten Sie alle geringfügigen Änderungen, die im Rahmen der Überprüfung / Annahme automatisch am Back-End vorgenommen wurden, auf dem gleichen Weg wie Sie Holen Sie sich alle anderen Code-Änderungen auf Master.

Wenn sich herausstellt, dass der Back-End-Zweig viel mehr Arbeit benötigt und sich über einen bestimmten Zeitraum hinweg ändert, bevor er zum Master zusammengeführt wird (z. B. wenn während der Überprüfung größere Probleme auftreten), möchten Sie wahrscheinlich regelmäßige Zusammenführungen direkt durchführen von der Backend-Verzweigung in die Frontend-Verzweigung (damit Sie nicht Ihre gesamte Frontend-Arbeit auf veralteten Backend-Code stützen). Dies ist einfach, wenn Sie der einzige Entwickler sind, der beide Funktionen ausführt (da Sie wissen, ob Sie selbst größere Änderungen vornehmen), aber selbst wenn beide Funktionen von verschiedenen Entwicklern parallel bearbeitet werden, sollte dies in Ordnung sein. Sie müssen nur in der Kommunikation bleiben (was Sie ohnehin benötigen würden, wenn Sie parallel an Aufgaben arbeiten, bei denen eine kritische Abhängigkeit von der anderen besteht).

Wenn sich herausstellt, dass die gesamte Backend-Verzweigung aufgegeben werden muss und niemals zusammengeführt wird (es scheint, als ob dies ein ziemlich wichtiger Deal wäre, der selten passieren würde), wählen Sie entweder Ihre Commits für eine neue Verzweigung aus, die vom Master kommt ohne die Backend-Arbeit oder Sie wenden Reverse Commits an, die den gesamten Backend-Code für den Frontend-Zweig entfernen. Aber wie ich sehen kann, würde es wahrscheinlicher sein, die Frontend-Arbeit anzuhalten, bis Sie herausgefunden haben, was das Backend ersetzen würde, das Sie herauswerfen, und dann zu entscheiden, was zu tun ist.

Ben
quelle
2

Ich sehe das Problem hier nicht.

Dies haben Sie bereits jedes Mal in Ihrer masterBranche, die sich ständig ändert, während Features entwickelt und dann zusammengeführt werden.

In Ihrem konkreten Beispiel legen Sie also zunächst die feature_xxx_backendVerzweigung an und entwickeln die Backend-Änderungen. In diesem Fall wird der Zweig überprüft und nach Abschluss masterder Überprüfung zusammengeführt.

Starten Sie einfach einen anderen Zweig feature_yyy_frontend. Sie werden wahrscheinlich direkt von dort verzweigen wollen feature_xxx_backend, damit Sie diese Änderungen bereits in Ihrer Datenbank haben. Entwickeln Sie dann einfach das Frontend-Feature, sobald die Verzweigung vorhanden ist master.

Wenn sich die feature_xxx_backendVerzweigung ändert, z. B. weil während der Überprüfung Dinge auftauchen, die behoben werden müssen, nehmen Sie diese Änderungen einfach vor und führen Sie sie in der feature_yyy_frontendVerzweigung zusammen. Fahren Sie dann mit dem Frontend-Zweig fort.

Sobald die Überprüfung des Backend-Zweigs abgeschlossen ist, wird es in zusammengeführt master. Zu diesem Zeitpunkt ist es ratsam, die feature_yyy_frontendVerzweigung auf eine neue Basis zu stellenmaster , sodass die Prüfer nur die neuen Änderungen überprüfen müssen, zu denen diese Verzweigung beiträgt master, und nicht die Änderungen, die für das Backend vorgenommen wurden (die bereits genehmigt wurden) ).

Dies ist auch möglich, wenn Sie zwei, drei oder mehr abhängige Zweige haben. Wenn Sie zwei Feature-Zweige haben, von denen Sie abhängig sind, erstellen Sie einfach einen abgeleiteten Zweig, in dem beide Features zusammengeführt wurden. Verzweigen Sie von dort aus, entwickeln Sie das dritte Feature und führen Sie beide Feature-Zweige zusammen, wenn sich diese ändern. Wenn beide Features fertig sind und entweder in den abgeleiteten Zweig eingefügt werden, führen Sie einen Neustart auf diesen Zweig durch, oder führen Sie einen Neustart auf den Master durch, wenn sie in den Master eingefügt werden.

Das erneute Einrichten (wie oben vorgeschlagen) ist sehr leistungsfähig und hilft dabei, ein sauberes Protokoll der Änderungen zu führen, wodurch Überprüfungen erheblich vereinfacht werden.

Polygnom
quelle
2

Wie Polygnome bereits erwähnt hat, können Sie Ihren Frontend-Zweig anstelle der Master mit Ihrem Backend-Zweig zusammenführen. Selbst mit dem aktuellen Zweig-Setup, das Sie jetzt haben, können Sie einfach Folgendes tun:

git checkout frontend
git merge backend

oder einfach

git merge backend frontend

Beachten Sie jedoch, dass Sie Aktualisierungen aus dem Backend in das Frontend einbinden müssen, um Konflikte zu vermeiden, wenn Änderungen am Backend nicht akzeptiert werden und mehr Arbeit erforderlich ist. Sobald die Änderungen in den Master übernommen wurden, können Sie Ihr Frontend auf den Master zurücksetzen, um die Backend-Merge-Commits zu beseitigen.

Technisch könnten Sie auch alles mit Rebase machen, aber das wird die Commit-Historie Ihres Frontend-Zweigs durcheinander bringen. Woher ich komme, wird dies als schlechte Praxis angesehen. YMMV

Joris Meys
quelle
"Seltsam, dass niemand erwähnt hat, dass Sie Ihren Frontend-Zweig tatsächlich mit Ihrem Backend-Zweig anstelle der Master zusammenführen können:" Dies wurde bereits erwähnt, z. B. in meiner eigenen Antwort.
Polygnome
@Polygnome Frontend muss nicht direkt vom Backend verzweigt werden. Sie können sowohl vom Master als auch verzweigt werden, aber Sie können sie trotzdem zusammenführen. Ihre Antwort erwähnt das also eigentlich nicht.
Joris Meys
Eigentlich schlägt meine Antwort nicht vor, dass Sie direkt vom Backend aus verzweigen, sondern dass dies wahrscheinlich der richtige Weg ist (da Sie diese Änderungen sowieso in den Frontend-Zweig einbinden).
Polygnome
@Polygnome dann habe ich deine Antwort falsch verstanden. Speziell für Sie aktualisiert :-)
Joris Meys
Ich weiß nicht, wer dies abgelehnt hat, aber bitte sagen Sie mir, wo ich falsch liege, damit ich auch etwas lernen kann.
Joris Meys
1

Die meisten Antworten hier beschreiben den Vorgang des Zusammenführens der Änderungen vom zweiten Zweig zum ersten Zweig korrekt, zeigen jedoch nicht auf, wie Sie die Anzahl der Konflikte, die Sie möglicherweise lösen müssen, minimieren können.

Wenn Sie zwei große Änderungen haben, die Sie einzeln überprüfen möchten (wie featureAund featureB), erstellen Sie eine PR, die NICHT zum Zusammenführen gedacht ist, sondern um frühzeitig Feedback zu einem PoC von zu erhalten featureA.

Die Leute werden in der Lage sein, es schnell zu überprüfen (es ist nur ein PoC), und das Ziel ist es, das allgemeine Design oder den Ansatz zu validieren.

Anschließend können Sie an Feature A weiterarbeiten, eine Pull-Anforderung dafür erstellen und an Feature B verzweigen und daran arbeiten.

Der große Unterschied ist, dass Sie jetzt damit rechnen können, dass featureAsich nichts radikal ändert: Das Design und der Ansatz wurden bereits validiert. Die Codeüberprüfung und die erforderlichen Änderungen sind möglicherweise eher subtil und lokal als "Woops, Sie benötigen einen anderen Ansatz". Dadurch wird die Menge an Arbeit minimieren , die Sie brauchen , später zu tun , um zu verschmelzen featureBauf featureA‚s - Code, unabhängig von der Methode Sie wählten.

Alpha
quelle