Minimum Viable Git für Trunk-basierte Entwicklung
Weniger ist mehr, wenn es um ein leistungsstarkes – und überkompliziertes – Tool wie Git geht
Eli ist Mitbegründer und Co-CEO von trunk.io . Er hatte leitende Positionen im Engineering bei Microsoft, Uber und Google (das das von ihm mitbegründete Startup übernommen hat) inne. Sein Hauptaugenmerk liegt darauf, Teams dabei zu helfen, schneller bessere Software zu entwickeln.
Die Entwicklung in einer kollaborativen Umgebung ist ein komplizierter Vorgang, bei dem die Arbeit mehrerer Entwickler nachverfolgt und koordiniert werden muss. Viele von uns verwenden Git zur Versionskontrolle, um all diese Änderungen im Griff zu behalten. Aber in Linus' eigenen Worten ist Git „der Informationsmanager aus der Hölle“. Es bietet so viele Optionen und seltsame Zustände, dass Sie sich leicht an einem schlechten Ort wiederfinden können, bis Sie von Grund auf neu klonen müssen – selbst wenn Sie nichts falsch gemacht haben.
Viele von uns wissen, dass ein Entwickler die Git-Refspec und den zugrunde liegenden Merkle-Baum, auf dem sie basiert, studiert hat, aber ein Git-Experte zu sein, ist wahrscheinlich nicht in Ihrer Stellenbeschreibung. Ich kann problemlos Auto fahren, ohne zu verstehen, wie das Getriebe tatsächlich funktioniert, und am Ende des Tages ist Git nur ein Mittel zum Zweck.
Um das Beste aus Git herauszuholen, müssen Sie es bei der Trunk-basierten Entwicklung so wenig wie möglich verwenden . Schränken Sie die von Ihnen verwendeten Befehle ein, halten Sie Ihren Feature-Zweig auf dem neuesten Stand und standardisieren Sie die Nutzung als Team. Individuell können Sie die Freiheit genießen, zu tun, was Sie wollen. Aber als Team wird der Preis für die Freiheit mit Reibereien bezahlt.
Begrenzen Sie Ihre Git-Aktionen
Die am einfachsten zu implementierende Vorgehensweise für maximale Git-Effizienz besteht darin, sich an eine Teilmenge von Befehlen zu halten. Git kann viele Dinge tun, aber die überwiegende Mehrheit seiner Macht besteht nur darin, Ihnen zu helfen, aus schrecklichen Situationen herauszukommen. Die Anzahl der Befehle, die Git zulässt, und die Anzahl der Befehle, die Sie tatsächlich jemals aufrufen sollten , sind ziemlich unterschiedlich.
Ich wurde einmal von einem CTO gebeten, seinem Engineering-Team einen Kurs in Git für Fortgeschrittene zu geben. Meine Antwort war einfach:
Bis du Advanced Git brauchst, haben sich die Räder bereits vom Auto gelöst. Konzentrieren wir uns stattdessen auf die korrekte Verwendung von Core Git.
Hier sind die 10 Git-Befehle, die ich verwende, um meine Arbeit zu erledigen und gleichzeitig die Häufigkeit zu minimieren, mit der ich in der Git-Hölle lande:
Filialleitung
git checkout -t -b {branch-name}
Erstellen Sie eine Verzweigung, setzen Sie den Upstream auf die aktuelle Verzweigung und wechseln Sie zu dieser. Sie können dies auch über den Befehl "git branch" tun, aber es sind mehrere Befehle erforderlich. Da ich beim Erstellen immer zu einem Branch wechseln möchte, ist dieser Befehl prägnanter. Erstellen und checken Sie den Zweig auf einen Schlag aus. Normalerweise benenne ich alle meine Filialen eli/{work-being-done}.
git checkout {branch-name}
Wechseln Sie zu einer Filiale.
git branch -vvSehen Sie sich Ihre aktuellen Branches und deren Upstreams an.
git branch -D {branch-name}Löschen Sie einen lokalen Zweig, in der Regel, um veraltete/mit dem Hauptzweig zusammengeführte Zweige zu bereinigen.
Schieben & Ziehen
git fetch origin main:main
Ziehen Sie die Fernbedienung mainin Ihr lokales main, auch wenn Sie gerade nicht in der mainFiliale sind! Das ist das ; sehr nützlich, wenn Sie versuchen, das Neueste mainin einen PR-Zweig zu integrieren.
git push origin
Drücken Sie meinen Code auf die Fernbedienung; Ich werde wahrscheinlich viele Maschinen in CI hochfahren, um meine Arbeit zu überprüfen.
git pull
Aktualisieren Sie meinen lokalen Zweig mit der gleichnamigen Fernbedienung.
Begehen
git add -A .
Fügen Sie alles hinzu, woran ich arbeite (neue und bearbeitete Dateien).
git commit -am "work"Sehen Sie hier für einen tiefen Einblick in meine Gedanken zu lokalen Commit-Nachrichten
git merge main
Viel mehr dazu weiter unten. Ich bin pragmatisch und kein Rebaser und freue mich, meine lokale Niederlassung mit den Vorgängen von zu verunreinigen main.
Halten Sie Ihren Feature-Zweig ordnungsgemäß auf dem neuesten Stand
In meinem letzten Artikel habe ich besprochen, wie Landing-Code auf verwaltet wird main. Aber oft müssen Sie während der Entwicklung und sicherlich vor dem Zusammenführen über die neuesten Änderungen auf dem Laufenden sein, mainweil:
- Du benötigst ein Feature, das gelandet
mainist, um deine Feature-Arbeit zu erledigen. - Etwas hat sich
maingeändert und wenn Sie es nicht aufheben, wird es kaputt gehen, wenn Sie versuchen, Ihren Code zu landen. - Du willst einfach frisch bleiben, weil du Ingenieur bist und glänzende neue Dinge liebst.
Tür 1: git zusammenführen
Das ist meine Go-to-Merge-Strategie. Es ist einfach, zuverlässig und ohne Schnickschnack. Ein Basic git mergenimmt alle Änderungen, die in passiert sind, mainund führt sie zusammen mit Ihren Änderungen als Commits zusammen. Sie können bis zum Erbrechen über die Nachteile dieser schnörkellosen Lösung lesen, aber ich zucke ehrlich gesagt nur mit den Schultern und sage: „Das ist mir egal.“ Wenn Sie Ihre Work-Branches per Squash-Merge zusammenführen, wird mainall dieser Unsinn über Git-Log-Verschmutzung genau das.
Es spielt ehrlich gesagt keine Rolle, wie/warum/was in meine Arbeitsbranche kam. Was zählt, ist — baut es sich auf, funktioniert es und macht der Code das, was ich will? Der Rest ist akademisch.
In der Praxis, und ich bin ein sehr praktischer Ingenieur, git mergekönnen Sie Zusammenführungskonflikte sauber handhaben und zum Bauen zurückkehren. Sie lösen alle Zusammenführungskonflikte einmal – und schon kann es losgehen. Dies ist die beste Option für Anfänger, vielbeschäftigte fortgeschrittene Benutzer und diejenigen unter Ihnen, die nicht davon träumen, Git-Gurus zu werden.
Tür 2: Git-Rebase
Dies ist bei weitem die schlechteste Option. OK, ich weiß; Es gibt praktisch eine ganze Generation, die Rebase vs. Merge so etwas wie Tabulatoren vs. Leerzeichen betrachtet. Aber in „echten“ Projekten, in denen ein oder mehrere Teams täglich zu einem Repo fusionieren, erfordert Rebase die Auflösung von n Merge-Konflikten anstelle eines Merge- oder Squash-Rebase (mehr dazu weiter unten).
Darüber hinaus schreibt jede Rebasierung den Git-Verlauf neu, und das bedeutet, wenn Ihr Zweig ein entferntes Gegenstück hat, müssen Sie git push --forceseinen Verlauf mit dem neuen rebasierten Verlauf Ihres Zweigs stampfen. Theoretisch ist das in Ordnung, aber es besteht die Möglichkeit, dass Ihre vorherige Arbeit versehentlich auf eine Weise gelöscht wird, die nur sehr schwer wiederhergestellt werden kann. Es ist einfach viel gefährlicher als zu fusionieren und bereitet mir ehrlich gesagt Kopfschmerzen, wenn ich nur daran denke.
Für die Zwecke dieses Artikels habe ich versucht, eine neue Basis zu erstellen, nur um mich daran zu erinnern, wie sehr ich diesen Workflow nicht mag. Schauen Sie sich an, was ein einfacher Rebase-Befehl in mein Terminal spuckt:
An diesem Terminal ist so viel falsch. Ich erhalte Notizen zu Commit-Hashes – die möchte ich nicht sehen. Ich erhalte vier Zeilen gelber Hinweise, um mich daran zu erinnern, wie das Ganze funktioniert. Und ich bin jetzt in einem Workflow, nur um den Code mainin meinen Zweig zu bekommen. Der Entscheidungsbaum ist albern kompliziert; git rebase --skip- Was ist das?! Warum ist es in Ordnung, einen Commit zu überspringen? Weißt du was? Sag es mir nicht, weil ich arbeiten muss.
Tür 3: Git-Squash-Rebase
Sie wollen definitiv nicht, was sich hinter Tür 2 befindet, aber einige Leute sind eingefleischte Rebaser. Mein Mitbegründer, Co-CEO David Apirian, hat mir seinen geheimen Backstage-Eingang zum Rebase gezeigt und es ist irgendwie großartig. Wir nennen dies die Squash-Rebase .
Ich habe die Bedeutung der Git-Einfachheit wiederholt, aber mit diesem Ansatz können Sie Ihr Rebase haben und es auch essen. Sie erhalten die magische Schichtung einer Rebase ohne den Wahnsinn eines Standard-Rebase-Flows. Mit einem Squash-Rebase können Sie:
- Sehen Sie sich einen Unterschied Ihrer lokalen Commits an, bevor Sie sie auf GitHub übertragen.
- Machen Sie Ihren letzten Commit ganz einfach rückgängig.
- Vermeiden Sie es, GitHubs Ansicht Ihrer Pull-Anfrage mit einer Menge kleiner lokaler Commits zu verunreinigen.
Schritt 1 – Squash alle Ihre lokalen Commits:
git reset --soft $(git merge-base HEAD main) &&
git commit -am "" --allow-empty-message
git rebase main
Sie können dies alles in einem einzigen Uber-Befehl zusammenfassen, um die neueste Hauptdatei abzurufen, alle Ihre Commits zu quetschen und auf die neueste Hauptdatei zu rebasieren:
git reset --soft $(git merge-base HEAD main) &&
git commit -am "" --allow-empty-message &&
git fetch origin main:main &&
git rebase main
[alias]
smartcommit = !git add -A . && git commit -am "" --allow-empty-message
squash = !git reset --soft $(git merge-base HEAD main) && git commit -am "" --allow-empty-message
squashrebase = !git squash && git fetch origin main:main && git rebase main
smart = !git smartcommit && git squashrebase
Einer der cooleren Aspekte, wenn es darum geht, Ihre lokalen Commits immer zu quetschen, ist, dass an der Spitze git logall die Arbeit steht, die Sie im Zweig geleistet haben. Ihre Arbeit vor Ort ähnelt jetzt eher dem, wie die zusammengeführte PR von Squash aussehen wird, wenn sie in landet main.
Sie können jederzeit den letzten Commit von HEAD mit Ihrem lokalen Zweig ablegen und die gesamte Arbeit sehen, die Sie von erledigt haben main. Dies ähnelt der detaillierten Ansicht, die GitHub Ihnen über die Änderungen bietet, ermöglicht es Ihnen jedoch, in Ihrem Terminal zu bleiben und ein verwirrendes Umschalten zwischen zwei unterschiedlichen Benutzeroberflächen zu vermeiden.
Ich muss zugeben, dass ich beeindruckt war, als David mir diesen Workflow zum ersten Mal zeigte. Er hatte den Drachen größtenteils getötet rebaseund die Möglichkeit, alle Dateien, die Sie in Ihrem Zweig geändert haben, lokal anzuzeigen, ist super cool.
Während Squash-Rebasing Ihnen hilft, einen besseren Flusszustand aufrechtzuerhalten, ist die überwältigende Mehrheit der Entwickler besser dran, einfach zu fusionieren. Die falsche Verwendung von Rebase oder Squash-Rebase führt zu Reibungen, die die Produktivität beeinträchtigen.
Fallstricke der GitHub-Branch-Hilfe
GitHub bietet diese Einstellung ☝️ an, um vorzuschlagen, mainautomatisch in Ihren Zweig zu fusionieren, wenn er veraltet ist. Diese Einstellung ist oft kontraproduktiv. Ich möchte, dass meine lokale Niederlassung die einzige Quelle der Wahrheit für meine PR ist, und niemand sonst (einschließlich GitHub) sollte darauf drängen. Die Arbeit mit GitHub auf meinem persönlichen Zweig sollte eine Einbahnstraße sein. Ich codiere lokal und pushe.
Wenn Sie GitHub so konfigurieren, dass es mit dem Pushen von Updates an Ihren Arbeitszweig beginnt, fordern Sie, dass der Datenverkehr in die falsche Richtung geht. Und das ist ein Rezept für Schmerzen.
Dieses Problem tritt auch auf, wenn Code-Reviewer Ihnen kleine Commit-Vorschläge auf Ihrem Pull-Request hinterlassen und Sie sie unbekümmert anwenden. Wenn Sie dann irgendwelche Arbeiten an Ihrem lokalen Zweig durchführen, bevor Sie diese Änderungen vornehmen, haben Sie einen kleinen Sack voller Schmerzen geöffnet.
Ich stelle oft fest, dass ich mir das versehentlich selbst angetan habe, wenn ich versuche, meine Updates zurück auf die Fernbedienung zu pushen, und git mir sagt, dass ich nicht mehr synchron bin. An diesem Punkt habe ich zwei Möglichkeiten:
git push --forceund blasen Sie alles auf der Fernbedienung weg, nicht auf Ihrer lokalen Niederlassung. Im Allgemeinen ist alles mit dem Wort Kraft destruktiv und entmutigend.git merge origin/{my-work-branch}um die Remote-Änderungen mit der lokalen Ansicht des Zweigs zusammenzuführen.
Diese GitHub-Einstellung ️☝️ erfordert, dass PRs auf dem neuesten Stand sind, mainbevor sie darin zusammengeführt werden. Dies „löst“ im Allgemeinen das Potenzial, einen Defekt zu haben main; Es funktioniert jedoch nur mit sehr langsamen Repos. Sobald eine Handvoll Entwickler versucht, mehrere PRs pro Tag zusammenzuführen, landen sie in einem Wettlauf um die Zusammenführung main– oder führen andernfalls ständig eine Zusammenführung/Rebase mainin ihren Zweig durch, um wieder „auf dem neuesten Stand“ zu sein, und treten im Grunde gegen ihre Kollegen an als erster fusionieren. Schmerzlich. Wenn Sie diese Funktion möchten, aber kein Solo-Entwickler sind, möchten Sie wahrscheinlich stattdessen eine Merge-Warteschlange – dies ist der skalierbare Weg, um No-Broken-Main zu erreichen. Dies war uns wichtig genug, um es mit Trunk Merge zu realisieren .
Minimiere Git für maximalen Wert
Indem Sie Ihre Git-Nutzung so einfach wie möglich halten, geben Sie Entwicklern weniger Seile, an denen sie sich aufhängen müssen, und mehr Zeit für die Entwicklungsarbeit, die wirklich wichtig ist. Lassen Sie Git eine unterstützende Rolle spielen und nicht zum Protagonisten werden. Um eine vernünftige und kollaborative Entwicklungsumgebung aufrechtzuerhalten, denken Sie an Folgendes:
- Wählen Sie die kleinste zu verwendende Git-Oberfläche und bleiben Sie dabei.
- Verwalten Sie Ihre Upstream-Änderungen immer auf die gleiche Weise.
- Standardisieren Sie die Vorgehensweisen in Ihrem Team, damit auch Ihre Kollegen nicht aus dem Ruder laufen.

![Was ist überhaupt eine verknüpfte Liste? [Teil 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































