Führen Sie Fehlerbehebungen aus dem Stamm in alten Zweigen zusammen

9

Wir sind gerade dabei, in meinem Unternehmen von svn zu git zu wechseln (nach einem Jahr, in dem wir Menschen überzeugt haben, yay!).

Bisher ist dies alles zum Besseren, aber es gibt eine kleine Sache, die wir derzeit in unserem Workflow haben, dass ich auch kein gutes Äquivalent finden kann.

Derzeit arbeiten alle unsere Entwickler im Master. Einmal im Quartal verzweigen wir den Master in den Xx-Zweig, der später unsere neueste Version sein wird. Dies bedeutet, dass unser SVN-Repo so aussieht:

  • Kofferraum
  • Geäst
    • 3.8
    • 4.1
    • 4.2
    • ...

Wir verwenden keine Tags.

Hin und wieder wird eine dringende Fehlerbehebung entdeckt.

Der derzeitige Weg für uns ist:

  • Repariere es im Master
  • SVN führt den relevanten Bereich von Commits wieder in den relevanten Zweigen zusammen (möglicherweise unsere neueste Version, möglicherweise mehr).

Wir sind in der Raumfahrtindustrie tätig, daher sind unsere Niederlassungen langlebig und der Kunden-Upgrade-Prozess ist ziemlich lang, weshalb wir bisher so gearbeitet haben.

Wie wäre ein gutes Äquivalent in Git?

Bisher habe ich versucht, den Fehler in einem vom Master erzeugten Zweig zu beheben und diesen Zweig dann wieder in Master und in 4.3 (zum Beispiel) zusammenzuführen. Der Hotfix-Zweig enthält den Master-Verlauf, und alle Commits zwischen Master und 4.3 werden ebenfalls zusammengeführt, was wir nicht möchten.

Dinge, an die ich bisher denken konnte:

  • Ich habe mir die sehr erfolgreiche Git Workflow-Methode angesehen und ihre Lösung besteht darin, den Fehler im Release-Zweig zu beheben und ihn wieder zusammenzuführen, anstatt umgekehrt. Dies könnte in unserem Fall funktionieren, wäre jedoch ziemlich umständlich, da wir den ältesten Zweig, in dem wir den Fehler beheben möchten, bereits kennen müssen, bevor wir den Fehler tatsächlich beheben können.
  • Eine andere Lösung besteht darin, den Master zu reparieren und dann die Commits auszuwählen (wie wir es heute für die SVN-Zusammenführung tun). Das Ärgerliche dabei ist, dass wir in diesem Fall die Geschichte dessen verlieren, was wo zusammengeführt wurde, da Kirschpicks wie neue Commits aussehen und wir die Beziehung verlieren.

Was ist der "gute" Weg, dies zu tun? Sollten wir Commits in der Geschichte korrigieren oder Cherry Pick auswählen und manuell verfolgen, was zusammengeführt wurde, oder sogar etwas anderes?

Wenn ich wenig Produktionserfahrung mit Git habe, bin ich mir sicher, dass ich etwas verpasst habe.

jlengrand
quelle

Antworten:

9

Der Git Flow geht davon aus, dass Sie nur eine einzige unterstützte Version haben, wobei der masterZweig immer auf die neueste Version verweist. Da Sie mehrere Releases gleichzeitig unterstützen, können Sie diesen Workflow nicht 1: 1 kopieren. Nvies Git Flow ist ein sehr gutes Beispiel für eine Verzweigungsstrategie, aber Sie müssen sie an Ihre Bedürfnisse anpassen. Am wichtigsten ist, dass Sie mehrere aktive Release-Zweige haben.

Wenn Sie einen Fehler feststellen, müssen Sie einige Tests durchführen, um alle betroffenen Versionen zu ermitteln. Es reicht nicht aus, den Fix zuerst zu schreiben und dann als Hotfix wieder in den Release-Zweigen zusammenzuführen. Normalerweise erhalten Sie eine kontinuierliche Reihe betroffener Versionen. Sehr alte Versionen enthalten den Fehler möglicherweise nicht. Neuere Versionen haben diesen Fehler möglicherweise versehentlich behoben. Sie müssen den Fehler in jeder Version überprüfen, damit Sie überprüfen können, ob er nach dem Fix tatsächlich behoben ist. Wenn Sie den Fehler als automatisierten Testfall ausdrücken können, ist es ziemlich einfach, das problematische Commit über zu finden git bisectoder den Test für jede Version auszuführen:

for release in 3.8 4.1 4.2
do
  git checkout $release
  if ./testcase >release-$release.log
  then echo "$release ok"
  else echo "$release AFFECTED"
  fi
done

Jetzt haben Sie den Fix auf trunk/ geschrieben master. Dies ist problematisch, da sich der fehlerhafte Teil möglicherweise zwischen den Versionen geändert hat, sodass ein Patch normalerweise nicht für eine ältere Version gilt. Insbesondere masterhängt Code in möglicherweise von den in master verfügbaren Funktionen ab, die in älteren Versionen möglicherweise nicht vorhanden waren. Es ist daher sehr sinnvoll, dass ein Git-Commit auf seinen gesamten Verlauf verweist, nicht nur auf den Änderungssatz. Beim Zusammenführen wird der gesamte Verlauf abgerufen, von dem es abhängt.

Wenn Sie diesen Verlauf verwenden cherry-pickoder rebaseignorieren, wird ein neues Commit mit demselben Änderungssatz, jedoch einem anderen Verlauf aufgezeichnet. Wie bereits erwähnt, funktioniert dies nicht, wenn Ihre Codebasis auseinander gegangen ist.

Die „richtige“ Lösung besteht darin, den Fix als Hotfix auf die älteste betroffene Version zu schreiben. Anschließend führen Sie die älteste Version in die zweitälteste Version ein. Normalerweise enthält eine neuere Version alle Commits einer älteren Version. Dies ist also in Ordnung. Wenn sich die Dinge geändert haben, haben Sie jetzt die Möglichkeit, den Zusammenführungskonflikt manuell zu lösen. Anschließend fügen Sie jede Version in die nächst jüngere Version ein, bis Sie fertig sind. Dies führt zu einer ordnungsgemäßen Historie und vermeidet unnötige Arbeit, während nur Anstrengungen erforderlich sind, die ohnehin aufgewendet werden müssen. Insbesondere bringt Sie diese inkrementelle Zusammenführung in kleinen Schritten näher an den aktuellen Entwicklungsstand.

Als Diagramm:

| o normal commit |
| x hotfix        |
| ⇘ merging       |

3.8 --o-----------------x
       \                 ⇘
4.1     o--o--o-----------x'
               \           ⇘
4.2             o--o--o-----x''
                       \     ⇘
develop                 o--o--x'''--o--o
amon
quelle
2
Nehmen wir der Vollständigkeit halber an, der Test war ein wenig falsch und Version 3.7 hat den gleichen Fehler (sagen wir, er tritt nur in einem Randfall in 3.7 auf, aber in leichter zu testenden Fällen in 3.8+), wurde aber erst nach dem entdeckt Fix wurde so zusammengeführt. Würden Sie an diesem Punkt nur Kirschen pflücken?
Izkata
2
@Izkata Ja, zu diesem Zeitpunkt ist es nicht mehr möglich, so zu tun, als gäbe es eine vernünftige Geschichte. Daher ist das Kirschpflücken eine gute Möglichkeit, die Änderungen auf eine ältere Version anzuwenden. Dies bedeutet jedoch, dass die Release-Zweige auseinander gegangen sind und neuere Releases nicht mehr alle Commits älterer Releases enthalten. Daher sollten wir die Zusammenführungskette ab dem Release, das wir in den Entwicklungszweig geändert haben, erneut durchführen. Während der ersten Zusammenführung können wir jedoch die von Kirschen ausgewählten Änderungen verwerfen, da wir das Update bereits auf die neuere Version angewendet hatten.
Amon
Danke, dass du @amon antwortest. Ihre Antwort ist sehr vollständig und geht in die Richtung, in die ich bereits geschaut habe. Es ist also gut, eine Validierung zu haben. Wir werden unsere eigenen Branchenanforderungen übernehmen und den Git-Flow-Ansatz an etwas anpassen, das besser zu uns passt. Danke noch einmal!
Jlengrand