GitHub Flow

Probleme mit git-flow

Ich reise überall hin, um Leuten Git beizubringen, und in fast jedem Kurs und Workshop, den ich in letzter Zeit gehalten habe, wurde ich gefragt, was ich von git-flow halte. Ich antworte immer, dass ich es großartig finde – es hat ein System (Git), das eine Million möglicher Arbeitsabläufe hat, genommen und einen gut getesteten, flexiblen Arbeitsablauf dokumentiert, der für viele Entwickler auf eine ziemlich unkomplizierte Weise funktioniert. Es ist so etwas wie ein Standard geworden, so dass Entwickler zwischen Projekten oder Firmen wechseln können und mit diesem standardisierten Arbeitsablauf vertraut sind.

Es hat aber auch seine Probleme. Ich habe einige Meinungen von Leuten gehört, denen es nicht gefällt, dass neue Funktionszweige mit develop statt mit master gestartet werden, oder die Art und Weise, wie Hotfixes gehandhabt werden, aber das sind eher Kleinigkeiten.

Eines der größeren Probleme ist für mich, dass es komplizierter ist, als ich denke, dass die meisten Entwickler und Entwicklungsteams es tatsächlich brauchen. Es ist so kompliziert, dass ein großes Hilfsskript entwickelt wurde, um den Ablauf zu unterstützen. Das ist zwar cool, aber das Problem ist, dass es nicht in einer Git-GUI durchgesetzt werden kann, sondern nur auf der Kommandozeile, so dass die einzigen Leute, die den komplexen Workflow wirklich gut lernen müssen, weil sie alle Schritte manuell ausführen müssen, dieselben Leute sind, die mit dem System nicht vertraut genug sind, um es von der Kommandozeile aus zu benutzen. Das kann ein großes Problem sein.

Beide Probleme lassen sich leicht lösen, indem man den Prozess stark vereinfacht. Bei GitHub verwenden wir Git-Flow nicht. Wir verwenden einen viel einfacheren Git-Workflow, den wir schon immer verwendet haben.

Durch seine Einfachheit hat er eine Reihe von Vorteilen. Einer ist, dass er für die Leute leicht zu verstehen ist, was bedeutet, dass sie ihn schnell erlernen können und selten, wenn überhaupt, Fehler machen oder Schritte rückgängig machen müssen, die sie falsch gemacht haben. Ein weiterer Vorteil ist, dass wir kein Wrapper-Skript benötigen, um es durchzusetzen oder ihm zu folgen, so dass die Verwendung von GUIs und dergleichen kein Problem darstellt.

GitHub Flow

Warum verwenden wir also Git-Flow nicht bei GitHub? Nun, das Hauptproblem ist, dass wir ständig neue Projekte entwickeln. Der Git-Flow-Prozess ist weitgehend auf die „Veröffentlichung“ ausgelegt. Bei uns gibt es eigentlich keine „Releases“, weil wir jeden Tag – oft mehrmals am Tag – in die Produktion überführen. Wir können dies über unseren Chat-Room-Roboter tun, in dem auch unsere CI-Ergebnisse angezeigt werden. Wir versuchen, den Prozess des Testens und Versendens so einfach wie möglich zu gestalten, damit sich jeder Mitarbeiter dabei wohl fühlt.

Es gibt eine Reihe von Vorteilen, so regelmäßig zu verteilen. Wenn man alle paar Stunden testet, ist es fast unmöglich, eine große Anzahl von Fehlern einzubringen. Kleinere Probleme können zwar auftreten, aber dann können sie sehr schnell behoben und erneut bereitgestellt werden. Normalerweise müsste man einen ‚Hotfix‘ oder etwas anderes außerhalb des normalen Prozesses machen, aber es ist einfach Teil unseres normalen Prozesses – es gibt keinen Unterschied im GitHub-Flow zwischen einem Hotfix und einem sehr kleinen Feature.

Ein weiterer Vorteil der ständigen Bereitstellung ist die Möglichkeit, Probleme aller Art schnell zu beheben. Wir können auf Sicherheitsprobleme reagieren, auf die wir aufmerksam gemacht werden, oder wir können kleine, aber interessante Feature-Anfragen unglaublich schnell implementieren, wobei wir für diese Änderungen genau denselben Prozess verwenden können wie für die Entwicklung normaler oder sogar großer Features. Es ist alles derselbe Prozess, und er ist sehr einfach.

Wie wir es machen

Was ist GitHub Flow?

  • Alles, was sich im master-Zweig befindet, kann bereitgestellt werden
  • Um an etwas Neuem zu arbeiten, erstellen Sie einen beschreibend benannten Zweig von master (z. B.: new-oauth2-scopes)
  • Kommitieren Sie lokal zu diesem Zweig und pushen Sie Ihre Arbeit regelmäßig in den gleichnamigen Zweig auf dem Server
  • Wenn Sie Feedback oder Hilfe benötigen oder Sie denken, dass der Zweig bereit zum Zusammenführen ist, öffnen Sie einen Pull Request
  • Nachdem jemand anderes das Feature überprüft und abgezeichnet hat, können Sie es in Master zusammenführen
  • Wenn es zusammengeführt und nach „Master“ verschoben wurde, können und sollten Sie es sofort einsetzen

Das ist der gesamte Ablauf. Es ist sehr einfach, sehr effektiv und funktioniert für ziemlich große Teams – GitHub hat jetzt 35 Mitarbeiter, von denen vielleicht 15-20 gleichzeitig an demselben Projekt (github.com) arbeiten. Ich denke, dass die meisten Entwicklungsteams – Gruppen, die gleichzeitig an demselben logischen Code arbeiten, was zu Konflikten führen könnte – etwa so groß oder kleiner sind. Besonders diejenigen, die fortschrittlich genug sind, um schnelle und konsistente Einsätze zu machen.

So, lassen Sie uns jeden dieser Schritte der Reihe nach betrachten.

#1 – alles im Master-Zweig ist einsatzfähig

Dies ist im Grunde die einzige harte Regel des Systems. Es gibt nur einen Zweig, der eine bestimmte und konsistente Bedeutung hat, und wir haben ihn master genannt. Für uns bedeutet dies, dass er bereitgestellt wurde oder schlimmstenfalls innerhalb weniger Stunden bereitgestellt wird. Es ist unglaublich selten, dass dieser Zweig zurückgespult wird (der Zweig wird zu einem älteren Commit zurückgeschoben, um Arbeit rückgängig zu machen) – wenn es ein Problem gibt, werden Commits rückgängig gemacht oder neue Commits eingeführt, die das Problem beheben, aber der Zweig selbst wird fast nie zurückgerollt.

Der master-Zweig ist stabil und es ist immer, immer sicher, von ihm aus zu deployen oder neue Zweige zu erstellen. Wenn man etwas in den Master-Zweig verschiebt, das nicht getestet ist oder den Build kaputt macht, bricht man den Gesellschaftsvertrag des Entwicklerteams und fühlt sich normalerweise ziemlich schlecht dabei. Für jeden Zweig, den wir pushen, werden Tests durchgeführt und in den Chatroom gemeldet. Wenn Sie sie also nicht lokal durchgeführt haben, können Sie einfach zu einem Themenzweig (sogar einem Zweig mit einem einzigen Commit) auf dem Server pushen und darauf warten, dass Jenkins Ihnen mitteilt, ob er alles besteht.

Sie könnten einen deployed-Zweig haben, der nur aktualisiert wird, wenn Sie deployen, aber das machen wir nicht. Wir legen einfach die aktuell bereitgestellte SHA durch die Webapp selbst offen und curl sie, wenn wir einen Vergleich machen müssen.

#2 – Erstellen Sie beschreibende Zweige von master

Wenn Sie mit der Arbeit an etwas beginnen wollen, erstellen Sie einen beschreibend benannten Zweig vom stabilen master Zweig. Einige Beispiele in der GitHub-Codebasis wären derzeit user-content-cache-key, submodules-init-task oder redis2-transition. Dies hat mehrere Vorteile: Zum einen können Sie beim Abrufen die Themen sehen, an denen alle anderen gearbeitet haben. Ein weiterer Vorteil ist, dass man, wenn man einen Zweig für eine Weile verlässt und später zu ihm zurückkehrt, sich leicht daran erinnern kann, was es war.

Das ist gut, denn wenn wir auf die GitHub-Zweiglistenseite gehen, können wir leicht sehen, an welchen Zweigen kürzlich gearbeitet wurde und wie viel Arbeit sie ungefähr haben.

GitHub Zweigliste

Es ist fast wie eine Liste der kommenden Features mit dem aktuellen, groben Status. Diese Seite ist großartig, wenn Sie sie nicht benutzen – sie zeigt Ihnen nur Zweige an, an denen im Verhältnis zum aktuell ausgewählten Zweig bereits gearbeitet wird, und sortiert sie so, dass die zuletzt bearbeiteten Zweige ganz oben stehen. Wenn ich wirklich neugierig werde, kann ich auf die Schaltfläche „Vergleichen“ klicken, um zu sehen, was die tatsächliche vereinheitlichte Diff- und Commit-Liste für diesen Zweig ist.

Zum Zeitpunkt dieses Schreibens haben wir also 44 Zweige in unserem Repository mit ungemischter Arbeit in ihnen, aber ich kann auch sehen, dass nur etwa 9 oder 10 von ihnen in der letzten Woche gepusht worden sind.

#3 – Ständig in benannte Zweige pushen

Ein weiterer großer Unterschied zu Git-Flow ist, dass wir ständig in benannte Zweige auf dem Server pushen. Da das Einzige, worüber wir uns wirklich Gedanken machen müssen, master ist, bringt das Pushen auf den Server niemanden durcheinander oder verwirrt die Dinge – alles, was nicht master ist, ist einfach etwas, woran gearbeitet wird.

Es stellt auch sicher, dass unsere Arbeit immer gesichert ist, falls ein Laptop verloren geht oder die Festplatte ausfällt. Noch wichtiger ist, dass alle Beteiligten in ständiger Kommunikation stehen. Ein einfaches ‚git fetch‘ gibt dir im Grunde eine TODO-Liste von dem, woran jeder gerade arbeitet.

$ git fetchremote: Counting objects: 3032, done.remote: Compressing objects: 100% (947/947), done.remote: Total 2672 (delta 1993), reused 2328 (delta 1689)Receiving objects: 100% (2672/2672), 16.45 MiB | 1.04 MiB/s, done.Resolving deltas: 100% (1993/1993), completed with 213 local objects.From github.com:github/github * charlock-linguist -> origin/charlock-linguist * enterprise-non-config -> origin/enterprise-non-config * fi-signup -> origin/fi-signup 2647a42..4d6d2c2 git-http-server -> origin/git-http-server * knyle-style-commits -> origin/knyle-style-commits 157d2b0..d33e00d master -> origin/master * menu-behavior-act-i -> origin/menu-behavior-act-i ea1c5e2..dfd315a no-inline-js-config -> origin/no-inline-js-config * svg-tests -> origin/svg-tests 87bb870..9da23f3 view-modes -> origin/view-modes * wild-renaming -> origin/wild-renaming

Es lässt auch jeden sehen, durch einen Blick auf die GitHub Branch List Seite, woran jeder andere arbeitet, so dass sie sie inspizieren können und sehen, ob sie bei etwas helfen wollen.

#4 – öffne jederzeit einen Pull Request

GitHub hat ein erstaunliches Code-Review-System namens Pull Requests, von dem ich fürchte, dass nicht genug Leute es kennen. Viele Leute nutzen es für Open-Source-Arbeiten – ein Projekt aufspalten, das Projekt aktualisieren, einen Pull Request an den Maintainer schicken. Es kann aber auch einfach als internes Code-Review-System verwendet werden, was wir auch tun.

Eigentlich verwenden wir es mehr als eine Zweig-Konversationsansicht als ein Pull Request. Sie können Pull Requests von einem Zweig zu einem anderen in einem einzelnen Projekt (öffentlich oder privat) in GitHub senden, so dass Sie sie verwenden können, um zu sagen: „Ich brauche Hilfe oder eine Überprüfung zu diesem Thema“ zusätzlich zu „Bitte fügen Sie dies ein“.

frühe pr-Nachricht

Hier können Sie sehen, wie Josh Brian für die Überprüfung anmeldet und Brian mit einigen Ratschlägen zu einer der Codezeilen kommt. Weiter unten können wir sehen, wie Josh Brians Bedenken anerkennt und mehr Code einbringt, um sie zu beseitigen.

Mehr Diskussion

Schließlich kann man sehen, dass wir uns immer noch in der Testphase befinden – dies ist noch kein einsatzbereiter Zweig, wir benutzen die Pull Requests, um den Code zu überprüfen, lange bevor wir ihn tatsächlich in master für den Einsatz zusammenführen wollen.

Wenn du beim Fortschritt deiner Funktion oder deines Zweiges nicht weiterkommst und Hilfe oder Rat brauchst, oder wenn du ein Entwickler bist und einen Designer brauchst, um deine Arbeit zu überprüfen (oder umgekehrt), oder auch wenn du wenig oder gar keinen Code hast, aber einige Screenshot-Comps oder allgemeine Ideen, öffnest du eine Pull-Anfrage. Sie können Personen im GitHub-System mit einem @Benutzernamen versehen. Wenn Sie also die Überprüfung oder das Feedback bestimmter Personen wünschen, geben Sie diese einfach in der PR-Nachricht an (wie Sie es oben bei Josh gesehen haben).

Das ist cool, weil die Pull Request-Funktion es Ihnen ermöglicht, einzelne Zeilen im Unified Diff, einzelne Commits oder die Pull Request selbst zu kommentieren und alles inline in eine einzige Konversationsansicht zu ziehen.Wenn also jemand kommentiert, dass du etwas vergessen hast oder es einen Fehler im Code gibt, kannst du ihn beheben und in den Zweig pushen. GitHub zeigt die neuen Commits in der Konversationsansicht an und du kannst weiter an einem solchen Zweig arbeiten.

Wenn der Zweig schon zu lange offen ist und du das Gefühl hast, dass er nicht mehr mit dem Master-Zweig synchron ist, kannst du den Master-Zweig in deinen Themenzweig einbinden und weiterarbeiten. Sie können in der Pull Request Diskussion oder in der Commit-Liste leicht sehen, wann der Zweig das letzte Mal mit dem ‚Master‘ auf den neuesten Stand gebracht wurde.

Master Merge

Wenn alles in dem Zweig wirklich und wahrhaftig fertig ist und Sie das Gefühl haben, dass er bereit für die Bereitstellung ist, können Sie zum nächsten Schritt übergehen.

#5 – Merge nur nach Pull Request Review

Wir arbeiten nicht einfach direkt an master oder an einem Themenzweig und fügen es ein, wenn wir denken, dass es fertig ist – wir versuchen die Zustimmung von jemand anderem in der Firma zu bekommen. Das ist in der Regel ein +1 oder ein Emoji oder ein „:shipit:„-Kommentar, aber wir versuchen, jemand anderen dazu zu bringen, es sich anzusehen.

shipit comment

Wenn wir das bekommen und der Zweig die CI besteht, können wir ihn in den Master-Zweig für das Deployment einbinden, was den Pull Request automatisch schließt, wenn wir ihn pushen.

#6 – Deployment sofort nach der Überprüfung

Schließlich ist deine Arbeit fertig und wird in den masterZweig zusammengeführt. Das bedeutet, dass, selbst wenn Sie es jetzt nicht einsetzen, die Leute neue Arbeit darauf aufbauen werden und der nächste Einsatz, der wahrscheinlich in ein paar Stunden stattfinden wird, wird es hinausschieben. Da man also nicht möchte, dass jemand anderes etwas veröffentlicht, das man selbst geschrieben hat und das Dinge kaputt macht, neigen die Leute dazu, sich zu vergewissern, dass es wirklich stabil ist, wenn es zusammengeführt wird, und die Leute neigen auch dazu, ihre eigenen Änderungen zu veröffentlichen.

Unser Campfire-Bot, hubot, kann Verteilungen für jeden der Mitarbeiter durchführen, so dass ein einfaches:

hubot depoy github to production

den Code verteilen und alle notwendigen Prozesse ohne Ausfallzeit neu starten kann. Sie können sehen, wie häufig dies bei GitHub der Fall ist:

Unsere Lagerfeuerprotokolle

Sie können sehen, dass 6 verschiedene Personen (einschließlich eines Support-Mitarbeiters und eines Designers) an einem Tag etwa 24 Mal deployen.

Ich habe dies für Zweige mit einem Commit gemacht, der eine einzeilige Änderung enthält. Der Prozess ist einfach, geradlinig, skalierbar und leistungsstark. Man kann es mit Funktionszweigen mit 50 Commits machen, die 2 Wochen gebraucht haben, oder mit einem Commit, der 10 Minuten gedauert hat. Es ist ein so einfacher und reibungsloser Prozess, dass man sich nicht darüber ärgert, dass man ihn auch nur für einen Commit machen muss, was bedeutet, dass die Leute selten versuchen, den Prozess zu überspringen oder zu umgehen, es sei denn, die Änderung ist so klein oder unbedeutend, dass es einfach keine Rolle spielt.

Dies ist ein unglaublich einfacher und mächtiger Prozess. Ich denke, die meisten Leute würden zustimmen, dass GitHub eine sehr stabile Plattform hat, dass Probleme schnell behoben werden, wenn sie überhaupt auftauchen, und dass neue Funktionen in einem schnellen Tempo eingeführt werden. Es gibt keine Kompromisse bei der Qualität oder Stabilität, damit wir mehr Geschwindigkeit oder Einfachheit oder weniger Prozess bekommen.

Fazit

Git selbst ist ziemlich komplex zu verstehen, den Arbeitsablauf, den man damit benutzt, komplexer als nötig zu machen, fügt einfach nur mehr mentalen Aufwand zu jedermanns Tag hinzu. Ich würde immer dafür plädieren, ein möglichst einfaches System zu verwenden, das für Ihr Team funktioniert, und zwar so lange, bis es nicht mehr funktioniert, und dann die Komplexität nur dann zu erhöhen, wenn es unbedingt nötig ist.

Für Teams, die formelle Veröffentlichungen in längeren Abständen (einige Wochen bis einige Monate zwischen den Veröffentlichungen) durchführen müssen, und in der Lage sein müssen, Hot-Fixes und Wartungszweige und andere Dinge zu erledigen, die sich aus dem seltenen Versand ergeben, macht Git-Flow Sinn, und ich würde seine Verwendung sehr befürworten.

Für Teams, die eine Kultur des Versands aufgebaut haben, die jeden Tag in Produktion gehen, die ständig testen und bereitstellen, würde ich etwas einfacheres wie GitHub Flow empfehlen.

Leave a Reply