Git
Chapters ▾ 2nd Edition

6.2 GitHub - Mitwirken an einem Projekt

Mitwirken an einem Projekt

Nun, da unser Konto eingerichtet ist, lass uns einige Details durchgehen, die nützlich sein könnten, um dir zu helfen, an einem bestehenden Projekt mitzuarbeiten.

Forken von Projekten

Wenn du zu einem bestehenden Projekt beitragen möchtest, zu dem du keine Push-Berechtigungen hast, kannst du das Projekt „forken“. Wenn du ein Projekt „forkst“, erstellt GitHub eine Kopie des Projekts, die ganz dir gehört. Es befindet sich in deinem Namensraum (engl. namespace), und du kannst Daten dorthin pushen.

Anmerkung

In der Vergangenheit war der Begriff „Fork“ in diesem Zusammenhang etwas Negatives und bedeutete, dass jemand ein Open-Source-Projekt in eine andere Richtung lenkt, manchmal ein konkurrierendes Projekt erstellt und die Beitragenden aufgespaltet hat. In GitHub ist ein „Fork“ schlichtweg das gleiche Projekt in deinem eigenen Namensraum, so dass du Änderungen an einem Projekt öffentlich vornehmen kannst und dabei einen transparenten Ansatz verfolgst.

Auf diese Weise müssen sich Projekte nicht darum kümmern, Benutzer als Beteiligte hinzuzufügen, um ihnen Push-Zugriff zu geben. Jeder kann ein Projekt forken, dorthin pushen und seine Änderungen wieder in das originale Repository einbringen, indem er einen sogenannten Pull-Request erstellt, den wir als nächstes behandeln werden. Das eröffnet einen Diskussionsfaden mit Code-Review. Der Eigentümer und der Mitwirkende können dann über die Änderung kommunizieren, bis der Eigentümer mit ihr zufrieden ist und sie daraufhin zusammenführen (engl. merge) kann.

Um ein Projekt abzuspalten (engl. fork), gehst du auf die Projektseite und klickst auf die Schaltfläche „Fork“ oben rechts auf der Seite.

Die Schaltfläche „Fork“
Abbildung 88. Die Schaltfläche „Fork“

Nach ein paar Sekunden wirst du auf deine neue Projektseite weitergeleitet, mit deiner eigenen beschreibbaren Kopie des Codes.

Der GitHub Workflow

GitHub ist auf einen bestimmten Collaboration-Workflow ausgerichtet, der sich auf Pull-Requests konzentriert. Dieser Ablauf funktioniert unabhängig davon, ob du eng in einem Team, in einem einzigen gemeinsamen Repository, mit einem global verteilten Unternehmen oder einem Netzwerk von Fremden, über Dutzende von Forks, zusammenarbeitest und zu einem Projekt beiträgst. Er richtet sich nach dem Themen-Branches Workflow, der in Kapitel 3 Git Branching ausführlich besprochen wurde.

Im Prinzip funktioniert der Ablauf so:

  1. Forke das Projekt.

  2. Erstelle lokal einen Feature-Branch aus master.

  3. Mache einige Commits, um das Projekt zu bearbeiten.

  4. Pushe diesen Branch in dein GitHub-Projekt (den Fork).

  5. Eröffne einen Pull-Request auf GitHub.

  6. Diskutiere deine Änderung, optional: mache weitere Commits.

  7. Der Projekteigentümer merged oder schließt den Pull Request.

  8. Synchronisiere den aktualisierten master wieder mit deinem Fork.

Das ist im Grunde genommen der Integration-Manager-Workflow aus Kapitel 5 Integrationsmanager. Aber anstatt E-Mails zur Kommunikation und Überprüfung von Änderungen zu verwenden, verwenden Teammitglieder die webbasierten Tools von GitHub.

Schauen wir uns ein Beispiel an, wie man mit diesem Workflow eine Änderung an einem Open-Source-Projekt vorschlägt, das auf GitHub gehostet wird.

Hinweis

Du kannst für die meisten Aktionen das offizielle Werkzeug GitHub CLI anstatt die GitHub Weboberfläche nutzen. Das Werkzeug kann auf Windows, MacOS und Linux Systemen installiert werden. Gehe zu GitHub CLI homepage für weitere Informationen, Installationsanleitungen und Handbücher.

Anlegen eines Pull-Requests

Tony ist auf der Suche nach Code, der auf seinem programmierbaren Arduino-Mikrocontroller läuft und hat auf GitHub unter https://github.com/schacon/blink eine tolle Programmdatei gefunden.

Das Projekt, zu dem wir beitragen wollen
Abbildung 89. Das Projekt, zu dem wir beitragen wollen

Das einzige Problem ist, dass die Blinkfrequenz zu schnell ist. Wir finden es viel angenehmer, 3 Sekunden statt 1 Sekunde zwischen den einzelnen Zustandsänderungen zu warten. Lass uns also das Programm verbessern und es als Änderungsvorschlag an das Projekt senden.

Zuerst klicken wir, wie bereits erwähnt, auf die Schaltfläche 'Fork', um unsere eigene Kopie des Projekts zu erhalten. Unser Benutzername hier ist „tonychacon“, also ist unsere Kopie dieses Projekts unter https://github.com/tonychacon/blink zu finden und dort könnten wir es bearbeiten. Wir werden es aber lokal klonen, einen Feature-Branch erstellen, den Code ändern und schließlich diese Änderung wieder auf GitHub pushen.

$ git clone https://github.com/tonychacon/blink (1)
Cloning into 'blink'...

$ cd blink
$ git checkout -b slow-blink (2)
Switched to a new branch 'slow-blink'

$ sed -i '' 's/1000/3000/' blink.ino (macOS) (3)
# If you're on a Linux system, do this instead:
# $ sed -i 's/1000/3000/' blink.ino (3)

$ git diff --word-diff (4)
diff --git a/blink.ino b/blink.ino
index 15b9911..a6cc5a5 100644
--- a/blink.ino
+++ b/blink.ino
@@ -18,7 +18,7 @@ void setup() {
// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  [-delay(1000);-]{+delay(3000);+}               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  [-delay(1000);-]{+delay(3000);+}               // wait for a second
}

$ git commit -a -m 'Change delay to 3 seconds' (5)
[slow-blink 5ca509d] Change delay to 3 seconds
 1 file changed, 2 insertions(+), 2 deletions(-)

$ git push origin slow-blink (6)
Username for 'https://github.com': tonychacon
Password for 'https://tonychacon@github.com':
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 340 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To https://github.com/tonychacon/blink
 * [new branch]      slow-blink -> slow-blink
  1. Wir klonen unseren Fork des Projekts lokal.

  2. Wir erstellen einen Branch mit prägnantem Namen.

  3. Wir nehmen unsere Anpassung am Code vor.

  4. Wir überprüfen, ob die Änderung gut ist.

  5. Wir committen unsere Änderung in den Feature-Branch.

  6. Wir pushen unseren neuen Feature-Branch zurück zu unserer GitHub-Fork.

Wenn wir nun zu unserem Fork auf GitHub zurückkehren, können wir sehen, dass GitHub bemerkt hat, dass wir einen neuen Feature-Branch gepusht haben. GitHub zeigt uns einen großen grünen Button, um unsere Änderungen zu überprüfen und einen Pull Request zum ursprünglichen Projekt zu öffnen.

Du kannst alternativ auch die Seite „Branches“ bei https://github.com/<user>/<project>/branches aufzurufen, um deinen Branch auszuwählen und von dort aus einen neuen Pull Request zu öffnen.

Die Schaltfläche Pull Request
Abbildung 90. Die Schaltfläche Pull Request

Wenn wir auf die grüne Schaltfläche klicken, sehen wir einen Bildschirm, auf dem du aufgefordert wirst, deinen Pull Request einen Titel und eine Beschreibung zu geben. Es ist fast immer sinnvoll, sich hierfür ein bisschen Mühe zu geben. Eine gute Beschreibung hilft dem Eigentümer des ursprünglichen Projekts, festzustellen, warum du die Änderungen machst, ob deine vorgeschlagenen Änderungen korrekt sind und ob die Annahme der Änderungen das ursprüngliche Projekt verbessern würden.

Wir erhalten auch eine Liste der Commits in unserem Feature-Branch, die dem master Branch „voraus“ (engl. ahead) sind (in diesem Fall nur der eine) und ein vereinheitlichtes Diff aller Änderungen, die vorgenommen werden, falls dieser Branch vom Projektleiter gemerged wird.

Seite zur Erstellung von Pull-Requests
Abbildung 91. Seite zur Erstellung von Pull-Requests

Wenn du in diesem Fenster auf die Schaltfläche 'Create pull request' klickst, wird der Eigentümer/Leiter des Projekts, für das du eine Abspaltung (engl. Fork) vorgenommen hast, benachrichtigt. Er wird informiert, dass jemand eine Änderung vorschlägt, und verlinkt auf eine Seite, die alle diese Informationen enthält.

Anmerkung

Pull-Requests werden häufig für öffentliche Projekte wie dieses verwendet, wenn die Änderungen der Beitragende vollständige Änderung sind. Sie werden jedoch auch zu Beginn des Entwicklungszyklus in internen Projekten verwendet. Da du den Feature-Branch auch nach dem Öffnen des Pull-Requests weiter bearbeiten kannst, wird er oft früh geöffnet. Er bietet die Möglichkeit, um die Arbeit als Team in einem Gesamtkontext zu iterieren, anstatt ihn erst am Ende des Prozesses zu öffnen.

Iteration eines Pull-Requests

An dieser Stelle kann sich der Projektverantwortliche die vorgeschlagene Änderung ansehen und mergen, ablehnen oder kommentieren. Nehmen wir an, er mag die Idee, würde aber eine etwas längere Zeit bevorzugen, in der das Licht aus ist.

Während diese Unterhaltung über E-Mail in den in Kapitel5 Verteiltes Git dargestellten Workflows stattfinden kann, geschieht dies bei GitHub online. Der Projektverantwortliche kann das vereinheitlichte Diff überprüfen und einen Kommentar hinterlassen, indem er auf eine der Zeilen klickt.

Pull-Request Zeilen-Kommentar
Abbildung 92. Kommentar zu einer bestimmten Codezeile in einem Pull-Request

Sobald der Betreuer diesen Kommentar abgibt, erhält die Person, die den Pull-Request geöffnet hat (und auch alle anderen, die das Repository beobachten), eine Benachrichtigung. Wir werden das später noch einmal anpassen, aber wenn er E-Mail-Benachrichtigungen eingeschaltet hat, bekommt Tony eine E-Mail wie diese:

E-Mail-Benachrichtigung
Abbildung 93. Kommentare, als E-Mail-Benachrichtigungen gesendet

Jeder kann auch allgemeine Kommentare zum Pull Request hinterlassen. Auf der Pull Request Diskussions-Seite sehen wir ein Beispiel dafür, wie der Projektleiter sowohl eine Zeile Code kommentiert als auch einen allgemeinen Kommentar im Diskussionsbereich hinterlässt. Du siehst, dass auch die Code-Kommentare in das Diskussionsfenster sichtbar sind.

Pull Request Diskussions-Seite
Abbildung 94. Pull Request Diskussions-Seite

Jetzt kann der Beitragende sehen, was er tun muss, damit seine Änderung akzeptiert wird. Zum Glück ist das sehr einfach. Wo du über E-Mail deine Daten erneut in die Mailingliste eintragen musst, committest du mit GitHub einfach erneut in den Feature-Branch und pushst, wodurch der Pull-Request automatisch aktualisiert wird. Im finalen Pull-Request siehst du auch, dass der alte Code-Kommentar in dem aktualisierten Pull-Request zusammengeklappt wurde, da er auf eine inzwischen geänderte Zeile basiert.

Das Hinzufügen von Commits zu einem bestehenden Pull Request löst keine weitere Benachrichtigung aus. Nachdem Tony seine Korrekturen gepusht hat, beschließt er, einen Kommentar zu hinterlassen, um den Projektträger darüber zu informieren, dass er die gewünschte Änderung vorgenommen hat.

finaler Pull-Request
Abbildung 95. finaler Pull-Request

Eine bemerkenswerte Besonderheit ist, dass du den „vereinheitlichten“ Diff erhältst, wenn du auf die Registerkarte „Files Changed“ in diesem Pull-Request klickst – d.h. die gesamte aggregierte Differenz, die in deinen Hauptbranch eingebracht würde, wenn dieser Feature-Branch gemerged würde. Im Sinne von git diff zeigt es dir grundsätzlich automatisch git diff master…<branch> für den Branch, auf dem dieser Pull Request basiert. Siehe Kapitel 5 Festlegen, was eingebracht wird für weitere Informationen über diese Art von Diffs.

Außerdem prüft GitHub, ob der Pull-Request sauber mergen würde und stellt eine Schaltfläche zur Verfügung, mit der du den Merge auf dem Server durchführen könntest. Diese Schaltfläche erscheint nur, wenn du Schreibzugriff auf das Repository hast und ein trivialer Merge möglich ist. Wenn du darauf klickst, führt GitHub einen „non-fast-forward“-Merge durch, was bedeutet, dass selbst wenn es sich bei dem Merge um einen schnellen Vorlauf (engl. fast-forward) handeln könnte, immer noch ein Merge-Commit erstellt wird.

Wenn du möchtest, kannst du den Branch einfach herunterladen (engl. pull) und lokal zusammenführen (engl. merge). Wenn du diesen Branch mit dem master Branch mergst und ihn nach GitHub pushen willst, wird der Pull Request automatisch geschlossen.

Das ist der grundsätzliche Workflow, den die meisten GitHub-Projekte verwenden. Feature-Branches werden erstellt, Pull-Requests werden geöffnet, es folgt eine Diskussion, möglicherweise wird eine weitere Überarbeitung des Branches durchgeführt und schließlich wird der Request entweder geschlossen oder zusammengeführt.

Anmerkung
Nicht nur Forks

Es ist wichtig zu erwähnen, dass du auch einen Pull-Request zwischen zwei Branches im selben Repository öffnen können. Wenn du mit jemandem an einer Funktion arbeitest und beide Schreibrechte auf das Projekt haben, kannst du einen Feature-Branch in das Repository verschieben und einen Pull-Request darauf an den master Branch desselben Projekts öffnen, um den Code-Review- und Diskussionsprozess einzuleiten. Es ist kein Forking notwendig.

Erweiterte Pull-Requests

Nachdem wir nun die Grundlagen für einen Beitrag zu einem Projekt auf GitHub erläutert haben, möchten wir dir einige interessante Tipps und Tricks zu Pull-Requests geben, damit du diese effektiver nutzen kannst.

Pull-Requests als Patches

Es ist wichtig zu verstehen, dass viele Projekte Pull-Requests nicht wirklich als eine Reihe perfekter Patches betrachten, die sauber angewendet werden sollten, so wie es bei den meisten Mailinglisten-basierten Projekte mit Patch-Serienbeiträge ist. Die meisten GitHub-Projekte betrachten Pull-Request-Branches als iterative Dialoge für vorgesehen Änderungen. Dies führt in der Regel zu einem vereinheitlichten Diff, der am Ende gemerged wird.

Das ist ein wichtiger Unterschied, denn im Allgemeinen wird die Änderung vorgeschlagen, bevor der Code fertig ist, was bei Beiträgen von Patch-Serien auf Mailinglistenbasis weitaus seltener ist. So kann früher mit den Projekt-Betreuern gesprochen werden und somit ist die richtige Lösung eher eine Art Gemeinschaftsarbeit. Wenn Code mit einem Pull-Request vorgeschlagen wird und die Maintainer oder die Community eine Änderung vorschlagen, wird die Patch-Serie im Allgemeinen nicht neu aufgerollt. Es wird der Unterschied als neuer Commit an den Branch weitergegeben (gepusht), wodurch der Dialog an dieser Stelle im intakten Kontext der vorherigen Arbeit fortgesetzt wird.

Wenn du beispielsweise zurückgehen und dir den finalen Pull-Request erneut ansehen willst, wirst du feststellen, dass der Beitragende seinen Commit nicht rebased und einen weiteren Pull-Request geöffnet hat. Stattdessen wurden neue Commits hinzugefügt und sie in den bestehenden Branch gepusht. Wenn du dir also zu einen späterem Zeitpunkt den Pull Request nochmal anschaust, kannst du den gesamten Kontext finden, in dem die Entscheidungen getroffen wurden. Wenn du auf der Website auf die Schaltfläche „Merge“ klickst, wird ein Merge-Commit erstellt, der auf den Pull-Request verweist. Somit kannst du bei Bedarf sehr schnell die ursprüngliche Diskussion begutachten.

Mit dem Upstream Schritt halten

Wenn dein Pull-Request veraltet ist oder anderweitig nicht sauber zusammengeführt wird, solltest du ihn reparieren, damit der Betreuer ihn leicht mergen kann. GitHub wird das für dich testen und dich am Ende jedes Pull Requests darüber informieren, ob das Merge trivial ist oder nicht.

PR merge Fehlschlag
Abbildung 96. Pull Request lässt sich nicht sauber mergen

Wenn du etwa „Pull Request lässt sich nicht sauber mergen“ siehst, solltest du deinen Branch so reparieren, dass er grün wird und der Maintainer keine zusätzliche Arbeit leisten muss.

Du hast grundsätzlich zwei Möglichkeiten, wie du das realisieren kannst. Du kannst deinen Branch entweder auf den Ziel-Branch rebasen (normalerweise den master Branch des von dir geforkten Repositorys), oder du kannst den Ziel-Branch mit deinem Branch mergen.

Die meisten Entwickler auf GitHub werden sich aus den gleichen Gründen für Letzteres entscheiden, die wir im vorherigen Abschnitt erläutert haben. Was wichtig ist, ist die Verlaufskontrolle und der endgültige Merge, so dass das Rebasing nicht viel mehr bringt als eine etwas aufgeräumtere Historie. Im Gegenzug ist es viel schwieriger und fehleranfälliger.

Wenn du im Ziel-Branch mergen willst, um deinen Pull-Request zusammenzuführen zu können, solltest du das ursprüngliche Repository als neuen Remote hinzufügen. Dann machst du ein git fetch darauf, führst den Haupt-Branch dieses Repositorys in deinem Feature-Branch zusammen, behebst alle Probleme und pushst es schließlich wieder in den gleichen Branch, in dem du den Pull-Request geöffnet hast.

Nehmen wir zum Beispiel an, dass der ursprüngliche Autor in dem von uns zuvor verwendeten Beispiel „tonychacon“ eine Änderung vorgenommen hat, die zu einem Konflikt im Pull-Request führt. Gehen wir diese Schritte einzeln durch.

$ git remote add upstream https://github.com/schacon/blink (1)

$ git fetch upstream (2)
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (3/3), done.
Unpacking objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
From https://github.com/schacon/blink
 * [new branch]      master     -> upstream/master

$ git merge upstream/master (3)
Auto-merging blink.ino
CONFLICT (content): Merge conflict in blink.ino
Automatic merge failed; fix conflicts and then commit the result.

$ vim blink.ino (4)
$ git add blink.ino
$ git commit
[slow-blink 3c8d735] Merge remote-tracking branch 'upstream/master' \
    into slower-blink

$ git push origin slow-blink (5)
Counting objects: 6, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 682 bytes | 0 bytes/s, done.
Total 6 (delta 2), reused 0 (delta 0)
To https://github.com/tonychacon/blink
   ef4725c..3c8d735  slower-blink -> slow-blink
  1. Das Original-Repository als Remote mit der Bezeichnung upstream hinzufügen.

  2. Die neueste Arbeit von diesem Remote abrufen (engl. fetch).

  3. Den Haupt-Branch dieses Repositorys mit dem Feature-Branch mergen.

  4. Den aufgetretenen Konflikt beheben.

  5. Zum gleichen Feature-Branch zurück pushen.

Sobald du das getan hast, wird der Pull-Request automatisch aktualisiert und erneut überprüft, um festzustellen, ob er sauber zusammengeführt werden kann.

PR fixed
Abbildung 97. Pull-Request wird nun sauber zusammengeführt

Einer der großen Pluspunkte von Git ist, dass man das kontinuierlich tun kann. Wenn du ein sehr lang laufendes Projekt hast, könntest du leicht immer wieder aus dem Zielbranch heraus mergen und müsstest dich nur mit Konflikten befassen, die seit dem letzten Mal, als du zusammengeführt hast, aufgetreten sind; was den Prozess sehr überschaubar macht.

Wenn du den Branch unbedingt rebasen willst, um ihn aufzuräumen, könntest du das natürlich tun. Es wird jedoch dringend empfohlen, den Branch, auf dem der Pull-Request bereits geöffnet ist, nicht zu force-pushen. Wenn von Anderen gepullt wurde und weitere Arbeiten daran durchgeführt wurden, stößt man auf alle in Kapitel 3, Die Gefahren des Rebasing beschriebenen Probleme. Schiebe stattdessen den rebasten Branch zu einem neuen Branch auf GitHub und öffne einen brandneuen Pull Request mit Bezug auf den alten Branch und schließen den originalen Pull Request.

Referenzen

Möglicherweise lautet deine nächste Frage: „Wie verweise ich auf den alten Pull-Request?“. Es stellt sich heraus, dass es viele, viele Möglichkeiten gibt, auf andere Dinge Bezug zu nehmen, und zwar fast überall dort, wo man in GitHub schreiben kann.

Beginnen wir mit der Frage, wie man einen anderen Pull-Request oder ein Issue vergleicht. Alle Pull-Requests und Issues sind mit Nummern versehen und innerhalb des Projekts eindeutig. Beispielsweise ist es nicht möglich, Pull Request #3 und Issue #3 anzulegen. Wenn du auf einen Pull-Request oder ein Issue von einem anderen verweisen möchtest, kannst du einfach <num> in einen Kommentar oder eine Beschreibung eingeben. Du kannst auch präziser sein, wenn die Issue- oder Pull-Anforderung an einem anderen Ort liegen. Schreibe Benutzername<num>, wenn du dich auf ein Issue oder Pull Request beziehst, in einen Fork des Repositorys, in dem du dich befindest. Oder schreibe Benutzername/repo#<num>, um auf etwas in einem anderen Repository zu verweisen.

Schauen wir uns ein Beispiel an. Angenommen, wir haben den Branch aus dem vorherigen Beispiel rebased, einen neuen Pull-Request für ihn erstellt und jetzt wollen wir die alte Pull-Anforderung aus der neuen aufrufen. Wir möchten auch auf ein Problem im Fork des Repositorys und auf ein Problem in einem ganz anderen Projekt verweisen. Wir können die Beschreibung wie bei Querverweise in einem Pull-Request eingeben.

PR references
Abbildung 98. Querverweise in einem Pull-Request

Wenn wir diese Pull-Anfrage einreichen, werden wir sehen, dass alles wie in „Querverweise, die in einem Pull-Request erzeugt wurden“ dargestellt wird.

PR references rendered
Abbildung 99. Querverweise, die in einem Pull-Request erzeugt wurden

Bitte beachte, dass die vollständige GitHub-URL, die wir dort eingegeben haben, auf die benötigten Informationen gekürzt wurde.

Wenn Tony nun zurück geht und den ursprünglichen Pull-Request schließt, können wir sehen, dass GitHub automatisch ein Trackback-Ereignis in der Pull-Request Zeitleiste erstellt hat, indem er ihn im neuen Pull-Request erwähnt. Das bedeutet, dass jeder, der diesen Pull-Request aufruft, sieht, dass er geschlossen ist. Er kann leicht auf denjenigen zurückgreifen, der ihn ersetzt hat. Der Link wird in etwa wie in „Zurück zum neuen Pull-Request in der geschlossenen Pull-Request Zeitleiste“ aussehen.

PR closed
Abbildung 100. Zurück zum neuen Pull-Request in der geschlossenen Pull-Request Zeitleiste

Zusätzlich zu den Issue-Nummern kannst du auch auf einen bestimmten Commit per SHA-1 referenzieren. Du musst einen vollen 40-stelligen SHA-1 angeben. Wenn GitHub das in einem Kommentar sieht, wird er direkt auf den Commit verlinken. Wie bei Issues kannst du auch hier auf Commits in Forks oder anderen Repositorys verweisen.

GitHub-Variante von Markdown

Die Verknüpfung mit anderen Issues ist nur der Anfang von interessanten Dingen, die du mit fast jeder Textbox auf GitHub machen kannst. In Issue- und Pull-Request-Beschreibungen, Kommentaren, Code-Kommentaren und mehr, kannst du das sogenannte „GitHub Flavored Markdown“ verwenden. Markdown fühlt sich an wie das Schreiben in Klartext, hat aber umfangreiche Darstellungs-Optionen.

Im Beispiel für GitHub-Variante von Markdown, geschrieben und gerendert findest du ein Muster, wie Kommentare oder Text geschrieben und dann mit Markdown gerendert werden können.

Example Markdown
Abbildung 101. Beispiel für GitHub-Variante von Markdown, geschrieben und gerendert

Die GitHub-Variante von Markdown bietet mehr Möglichkeiten, als die normale Markdown-Syntax. Alle diese Funktionen können sehr nützlich sein, wenn du hilfreiche Pull-Request, Issue-Kommentare oder Beschreibungen erstellst.

Aufgabenlisten

Die wirklich praktische GitHub-spezifische Markdown-Funktion, vor allem für die Verwendung in Pull-Requests, ist die Aufgabenliste. Eine Aufgabenliste ist eine Liste von Kontrollkästchen für alle Vorgänge, die du erledigen möchtest. Wenn du sie in einen Issue oder Pull-Request einfügst, werden normalerweise Punkte angezeigt, die du erledigen sollst, bevor du den gesamten Vorgang als erledigt betrachten kannst.

Du kannst eine Task-Liste wie folgt anlegen:

- [X] Write the code
- [ ] Write all the tests
- [ ] Document the code

Wenn wir das in die Beschreibung unseres Pull Request oder Issue aufnehmen, sehen wir, dass es wie in Aufgabenliste in Markdown-Kommentar, gerendert dargestellt wird.

Example Task List
Abbildung 102. Aufgabenliste in Markdown-Kommentar, gerendert

Diese Funktion wird häufig in Pull Requests verwendet, um zu verdeutlichen, was du alles auf dem Branch erledigen möchtest, bevor der Pull Request bereit für die Zusammenführung ist. Der wirklich coole Teil ist, dass du einfach auf die Kontrollkästchen klicken kannst, um den Kommentar zu aktualisieren. Du musst nicht den Markdown bearbeiten, um Aufgaben als erledigt zu markieren.

Darüber hinaus sucht GitHub nach Aufgabenlisten in deinen Issues und Pull Requests und zeigt sie als Metadaten zu den Seiten an, auf denen sie stehen. Wenn du z.B. einen Pull-Request mit Aufgabenliste hast und dir die Übersichtsseite aller Pull-Requests ansiehst, kannst du sehen, wie weit er abgearbeitet ist. Das hilft den Teilnehmern, Pull-Requests in Teilaufgaben aufzuschlüsseln und anderen Teilnehmern, den Fortschritt des Branch zu verfolgen. Ein Beispiel dafür findest du bei: Task-Liste (Zusammenfassung) in der Pull-Request-Liste.

Example Task List
Abbildung 103. Task-Liste (Zusammenfassung) in der Pull-Request-Liste

Diese Funktion ist unglaublich nützlich, wenn du einen Pull Request frühzeitig öffnest und damit deinen Fortschritt bei der Realisierung des Features verfolgst (engl. track).

Code-Schnipsel

Du kannst auch Code-Schnipsel zu Kommentaren hinzufügen. Es ist dann besonders praktisch, wenn du etwas präsentieren möchtest, das du versuchen könntest, bevor du es tatsächlich als Commit auf deinem Branch einbaust. Das wird auch oft verwendet, um Beispielcode hinzuzufügen, der verrät, was nicht funktioniert oder was dieser Pull-Request umsetzen könnte.

Um ein Code-Schnipsel hinzuzufügen, musst du ihn in zwei 3-fach Backticks (`) „einzäunen“.

```java
for(int i=0 ; i < 5 ; i++)
{
   System.out.println("i is : " + i);
}
```

Wenn du den Namen der Programmiersprache hinzufügst, wie wir es mit java getan haben, wird GitHub versuchen, die Syntax hervorzuheben. Wie im Beispiel oben, würde es zu „eingezäuntes“, gerendertes Code-Schnipsel-Beispiel gerendert werden.

Rendered fenced code
Abbildung 104. „eingezäuntes“, gerendertes Code-Schnipsel-Beispiel

Quoten (Zitieren)

Wenn du auf einen kleinen Teil eines langen Kommentars reagieren willst, kannst du selektiv aus dem anderen Kommentar zitieren, indem du den Zeilen das Zeichen > voranstellst. Es ist sogar so häufig und nützlich, dass es eine Tastenkombination dafür gibt. Wenn du Text in einem Kommentar markierst, auf den du direkt antworten möchtest, und die Taste r drückst, wird dieser Text in der Kommentarbox für dich zitiert.

Zitate (engl. quotes) sehen in etwa so aus:

> Whether 'tis Nobler in the mind to suffer
> The Slings and Arrows of outrageous Fortune,

How big are these slings and in particular, these arrows?

Nach dem Rendern sieht der Kommentar wie folgt aus: gerendertes Zitat-Beispiel.

Rendered quoting
Abbildung 105. gerendertes Zitat-Beispiel

Emojis

Abschließend kannst du auch Emojis in deinen Kommentaren verwenden. Das wird in der Praxis sehr häufig verwendet. Du wirst es in vielen GitHub-Issues und Pull-Requests sehen. Es gibt sogar einen Emoji-Helfer in GitHub. Wenn du einen Kommentar eingibst und mit einem : (Doppelpunkt) beginnst, hilft dir ein Autokomplettierer, das Gesuchte schnell zu finden.

Emoji autocompleter
Abbildung 106. Autokomplettierer für Emojis in Aktion

Emojis haben die Erscheinungsform von :<name>: irgendwo im Kommentar. Zum Beispiel kannst du so etwas schreiben:

I :eyes: that :bug: and I :cold_sweat:.

:trophy: for :microscope: it.

:+1: and :sparkles: on this :ship:, it's :fire::poop:!

:clap::tada::panda_face:

Gerendert würde es in etwa so aussehen: Massive Emoji-Kommentare.

Emoji
Abbildung 107. Massive Emoji-Kommentare

Nicht, dass das äußerst sinnvoll wäre, aber es ergänzt ein Medium mit Spaß und Emotionen, was sonst nur schwer zu vermitteln wäre.

Anmerkung

Es gibt derzeit eine ganze Reihe von Webservices, die Emoji-Zeichen verwenden. Ein großartiger Spickzettel, zum Nachschlagen, um ein Emoji zu finden, das ausdrückt, was du sagen willst, findest du unter:

Bilder

Technisch gesehen ist das keine GitHub-Variante von Markdown, aber es ist sehr praktisch. Neben dem Hinzufügen von Markdown-Bildlinks zu Kommentaren, für die es schwierig sein kann, URLs zum Einbetten zu finden, kannst du mit GitHub Bilder per Drag&Drop in Textbereiche ziehen und so einbinden.

Drag and drop images
Abbildung 108. Bilder per Drag&Drop hochladen und automatisch einbetten

Wenn du dir Bilder per Drag&Drop hochladen und automatisch einbetten ansiehst, wirst du einen kleinen Hinweis, „Parsed as Markdown“, über dem Textfeld sehen. Wenn du darauf klickst, erhältst du einen vollständiges Cheat-Sheet (Spickzettel) mit allem, was du mit Markdown auf GitHub machen kannst.

Dein öffentliches GitHub-Repository aktuell halten

Sobald du ein GitHub-Repository geforkt hast, existiert dein Repository (dein „fork“) unabhängig vom Original. Insbesondere dann, wenn das ursprüngliche Repository neue Commits bekommen hat, informiert dich GitHub in der Regel durch eine Meldung wie:

This branch is 5 commits behind progit:master.

Aber dein GitHub-Repository wird nie automatisch von GitHub aktualisiert. Das ist etwas, was du selbst tun musst. Glücklicherweise ist das sehr einfach umzusetzen.

Die eine Möglichkeit erfordert keine Konfiguration. Wenn du z.B. von https://github.com/progit/progit2.git geforkt hast, kannst du deinen master Branch so auf dem neuesten Stand halten:

$ git checkout master (1)
$ git pull https://github.com/progit/progit2.git (2)
$ git push origin master (3)
  1. Wenn du dich in einem anderen Branch befindest, kehrst du zu master zurück

  2. Hole (engl. fetch) Änderungen von https://github.com/progit/progit2.git und merge sie in den master

  3. Pushen deinen master Branch nach origin

Das funktioniert, aber es ist lästig, die Fetch-URL jedes Mal neu eingeben zu müssen. Du kannst diese Arbeit mit ein wenig Konfiguration automatisieren:

$ git remote add progit https://github.com/progit/progit2.git (1)
$ git fetch progit (2)
$ git branch --set-upstream-to=progit/master master (3)
$ git config --local remote.pushDefault origin (4)
  1. Füge das Quell-Repository hinzu und gib ihm einen Namen Hier habe ich mich entschieden, es progit zu nennen

  2. Hole (engl. fetch) dir eine Referenz zu den Branches von progit, genauer gesagt vom master.

  3. Konfiguriere deinen master Branch so, dass er von dem progit Remote abgeholt (engl. fetch) wird

  4. Definiere das standardmäßige Push-Repository auf origin

Sobald das getan ist, wird der Workflow viel einfacher:

$ git checkout master (1)
$ git pull (2)
$ git push (3)
  1. Wenn du dich in einem anderen Branch befindest, kehre zum master zurück

  2. Fetche die Änderungen von progit und merge sie in master

  3. Pushe deinen master Branch nach origin

Dieser Herangehensweise kann nützlich sein, aber sie ist nicht ohne Nachteile. Git wird diese Aufgabe gerne im Hintergrund für dich erledigen, aber es wird dich nicht benachrichtigen, wenn du einen Commit zum master machst, von progit pullst und dann zu origin pushst – alle diese Operationen sind mit diesem Setup zulässig. Du musst also darauf achten, nie direkt an den master zu committen, da dieser Branch faktisch zum Upstream-Repository gehört.

scroll-to-top