Beiträge zu Free/Libre Open Source Software, Teil 2 Code via Pull Request unter GitHub beisteuern

Autor / Redakteur: Mirco Lang / Stephan Augsten

Git ist Standard bei der Versionsverwaltung, GitHub Beinahe-Standard bei den Git-Plattformen. Und Pull Requests wiederum sind das Standardverfahren, um Code auf GitHub beizusteuern – eine wichtige Grundlage, die jeder Entwickler kennen sollte.

Firma zum Thema

Umfasst ein Pull Request viele verschiedene Commits kann es hilfreich sein, die Änderungen per Squash in einen einzelnen Commit zusammenzufassen
Umfasst ein Pull Request viele verschiedene Commits kann es hilfreich sein, die Änderungen per Squash in einen einzelnen Commit zusammenzufassen
(Bild: Lang / GitHub)

GitHub wird durchaus im kommerziell-proprietären Umfeld genutzt, vor allem ist die Microsoft-Plattform aber für Open-Source-Projekte bekannt. Nun gibt es viele Möglichkeiten zu verschiedenen FLOSS-Projekten beizutragen, aber die wichtigsten Beiträge sind nach wie vor neuer Code und Code-Korrekturen.

Diese werden in aller Regel über Pull Requests eingebaut – dahinter steckt allerdings mehr als eine Referenz auf den Befehl „git pull“. Bei GitLab nennt sich die äquivalente Funktion Merge Request, meint dasselbe, und deutet ebenfalls auf mehr hin als den „git merge“-Befehl.

Bei Pull Requests geht es darum, Code bereitzustellen, einen Review-Prozess anzustoßen und schließlich tatsächlich die Patches mit dem Repo zu verschmelzen. Einer der großen Vorteile: Jeder GitHub-Nutzer kann jedem Projekt Änderungen vorschlagen, ohne anderweitig mit den Betreibern verbunden zu sein oder Kontakt aufnehmen zu müssen – es ist ein standardisierter Prozess mit sehr wenig Overhead.

Im Folgenden bilden wir den kompletten Prozess im Detail ab, sowohl aus Sicht des Beitragenden als auch des Verwalters des Repos. Der grundsätzliche Workflow sieht dabei folgendermaßen aus: Repo klonen, Feature-Branch anlegen, editieren, committen, pushen, Pull Request anlegen, Review-Prozess, Merge – und nun einmal Schritt für Schritt.

Pull Request einreichen

Schritt 1 findet auf Github.com statt: Forken Sie das Repo, zu welchem Sie beitragen möchten. Im Folgenden findet der Verständlichkeit halber alles an einem realen Repo mit echten URLs statt.

Nun wechseln Sie auf die Kommandozeile und klonen das Repository:

git clone https://github.com/bili123/cli-help.git

Jetzt sollten Sie das lokale Fork-Repo so einrichten, dass Sie Ihren Master vom Original-Master updaten und damit verschmelzen können – notwendig ist dies nicht:

git remote add upstream https://github.com/bili123/cli-help
git fetch upstream
git checkout master
git merge upstream/master

Anschließend kann mit der eigentlichen Arbeit begonnen werden – und die beginnt mit einem separaten Branch für das geplante Feature, die geplante Korrektur oder sonstige Änderung, also:

git branch mybranch
git checkout mybranch

Es folgen die Änderungen im Repo, ganz ohne jegliche Besonderheiten. Allerdings darf pro Branch wirklich nur ein Thema umgesetzt werden. Das ganze Prozedere endet wie gewohnt mit einem normalen „git commit“. Da dieser Commit für Dritte gedacht ist, sollten Sie ganz besonders auf eine gute, verständliche Commit-Nachricht achten.

Nun wird es wieder optional: Bevor die Commits gepushed werden, dient es sich an, nochmals ein Update vom Original-Master zu holen und etwaige in der Zwischenzeit neu hinzugekommene Commits per Rebase-Befehl in den Arbeits-Branch aufzunehmen – schlicht, um dem Projektverwalter das Leben einfacher zu machen:

git fetch upstream
git checkout master
git merge upstream/master
git checkout mybranch
git rebase master

Ein letzter Schritt lokal im Terminal – ganz wie zu erwarten:

git push --set-upstream origin mybranch

Somit liegen die Änderungen nun im geforkten Repo auf Github, wo es dann auch weitergeht: Über den Button „Compare and Pull Request“ gelangen Sie zum Formular für Pull Requests. Zunächst finden Sie hier den Vergleich zwischen dem originalen Master-Branch und Ihrem Entwicklungszweig, hier also „mybranch“. Sofern alles passt, können Sie den Pull Request absenden.

Alternativ lassen sich die Pull Requests auch als reine Drafts absenden, beispielsweise wenn das zu entwickelnde Feature noch in einem frühen Stadium ist und per Pull Request überhaupt geklärt werden soll, ob sich dessen Fertigstellung überhaupt lohnt. Essenziell ist der Draft-Status jedoch nicht, da der Verwalter des Original-Repos diesen Status ebenfalls nachträglich setzen kann. Pull Requests im Draft-Status können nicht verschmolzen werden, es ist lediglich eine kleine Absicherung.

Pull Request testen und einbauen

Nun wird die Perspektive gewechselt: Im Original-Repository erscheint nun also der eingereichte Pull Request, was den Verwalter mit vier Optionen konfrontiert: Pull Request akzeptieren und verschmelzen, ihn in den Draft-Status versetzen, ihn ablehnen oder schlicht kommentieren.

Vorab wird der Verwalter aber in der Regel testen wollen! Zunächst muss dafür die Datei .git/config angepasst werden, mit folgendem Eintrag unterhalb von [remote "origin"]:

fetch = +refs/pull/*/head:refs/pull/origin/*

Damit lassen sich nun alle Pull-Request-Zweige abfragen:

git fetch origin

Als Ergebnis gibt es eine durchnummerierte Liste, beispielsweise:

* [new ref]     refs/pull/8/head -> refs/pull/origin/8

Hier landet der Pull Request in Branch „8“, der sich natürlich auch auschecken lässt:

git checkout -b 8 pull/origin/8

Im Arbeitsverzeichnis sind nun die Änderungen des Pull Requests vorhanden und können getestet werden – allerdings im Read-only-Modus.

Standardmäßig wird nach dem Testen vor allem ein Kommentar folgen, sofern es sich nicht bloß um kleine Korrekturen handelt – es beginnt also ein Review-Prozess. Bei GitHub ist das erfreulich einfach gehalten: Die Diskussion kann direkt auf der Pull-Request-Seite im Browser ablaufen.

Weitere Commits, die vom Pull-Request-Ersteller aus dessen “mybranch”-Ast kommen, landen automatisch in eben diesem Pull Request. Es können also beliebige Anpassungen vorgenommen werden, ohne einen neuen Pull Request erstellen zu müssen. Nachdem alle Details besprochen, im Code umgesetzt und committed wurden, kann der Original-Verwalter den Pull Request final einbauen.

Am einfachsten gelingt dies über Github.com – natürlich auch hier mit Optionen: Wie üblich können Sie hier mit Merge, Rebase oder Squash & Merge arbeiten. Welche Option sich anbietet, hängt von Ihren eigenen, projektinternen Regularien ab, aber auch von der Vorgehensweise des Pull-Request-Erstellers – wenn dieser nämlich 50 einzelne Commits in den Pull Request packt, dürfte ein vorheriges Zusammenfassen per Squash in einen einzelnen Commit durchaus hilfreich sein.

Der finale Pull-Request-Merge auf GitHub.com.
Der finale Pull-Request-Merge auf GitHub.com.
(Bild: Lang / GitHub)

Einmal ausgewählt und gegebenenfalls kommentiert, schließt ein Klick auf den „Confirm Squash & Merge“-Button den Vorgang auf der Server-Seite ab. Alternativ zum Browser kann natürlich auch im Terminal gemerged werden – auf die ganz reguläre Art und Weise per Pull des „mybranch“-Zweigs aus dem geforkten Repository:

git checkout master
git pull https://github.com/FORKER_NAME/FORKER_REPO mybranch
git merge mybranch
git push origin master

Zum Abschluss bietet sich noch ein …

git branch -d mybranch

… an, um den bereits verschmolzenen Entwicklungszweig zu löschen.

Merge Request

Wenn Sie sich einigermaßen mit Git auskennen, dürfte klar geworden sein: Im Grunde handelt es sich bei Pull Requests schlicht um Merges von Entwicklungszweigen Dritter. Bei GitHub heißt es Pull Request nach der ersten Aktion im Original-Repo, dem „Besorgen“ des Zweigs, bei GitLab heißt es Merge Request nach der letzten Aktion im Original-Repo, dem Verschmelzen des Zweigs.

Grundsätzlich ist der Pull-Request-Workflow ziemlich simpel, auch wenn der Umgang damit nicht wirklich intuitiv ist und zumindest im Terminal hier und da etwas frickelig, wenn man sich etwa das Pullen von Pull-Request-Zweigen anschaut. Aber natürlich wird auch dieser Git-Workflow komplexer, wenn von vielen Seiten daran gearbeitet wird, Konflikte auftreten oder auch schlicht Unfälle beim Mergen oder Rebasen passieren.

Insofern zum Ende noch der – hoffentlich – wirklich sehr offensichtliche Tipp: Bevor Sie damit produktiv werden, sollten Sie ein zweites Github-Konto anlegen und testen, testen, testen.

(ID:47077869)

Über den Autor

 Mirco Lang

Mirco Lang

Freier Journalist & BSIler