Git
Chapters ▾ 2nd Edition

6.2 GitHub - Mitwirken an einem Projekt

Mitwirken an einem Projekt

Nun, da unser Konto eingerichtet ist, lassen Sie uns einige Details durchgehen, die nützlich sein könnten, um Ihnen zu helfen, zu einem bestehenden Projekt beizutragen.

Forken von Projekten

Wenn Sie zu einem bestehenden Projekt beitragen möchten, zu dem Sie keinen Push-Zugang haben, können Sie das Projekt „forken“. Wenn Sie ein Projekt „forken“, erstellt GitHub eine Kopie des Projekts, die ganz Ihnen gehört; es befindet sich in Ihrem Namensraum (engl. namespace), und Sie können Daten dorthin „hochladen“ (engl. push).

Note

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 Ihrem eigenen Namensraum, so dass Sie Änderungen an einem Projekt öffentlich vornehmen können, um einen transparenten Ansatz zu verfolgen.

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), gehen Sie auf die Projektseite und klicken Sie auf die Schaltfläche „Fork“ oben rechts auf der Seite.

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

Nach ein paar Sekunden werden Sie auf Ihre neue Projektseite weitergeleitet, mit Ihrer 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 Sie eng in einem Team, in einem einzigen gemeinsamen Repository, mit einem global verteilten Unternehmen oder einem Netzwerk von Fremden, über Dutzende von Forks, zusammenarbeiten und zu einem Projekt beitragen. Es ist um den Workflow aus Themen-Branches konzentriert, der in Kapitel 3 Git Branching ausführlich besprochen wird.

Im Prinzip funktioniert der Ablauf so:

  1. Forken Sie das Projekt

  2. Erstellen Sie lokal einen Themen-Branch aus master.

  3. Machen Sie einige Commits, um das Projekt zu überarbeiten.

  4. Pushen Sie diesen Branch zu Ihrem GitHub-Projekt.

  5. Eröffnen Sie einen Pull-Request auf GitHub.

  6. Diskutieren Sie die optionale Fortsetzung des Commits.

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

  8. Synchronisieren Sie den aktualisierten Master wieder mit Ihrem 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 Anpassung an einem Open-Source-Projekt vorschlägt, das auf GitHub gehostet wird.

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
Figure 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. Lassen Sie uns also das Programm verbessern und es als Änderungsvorschlag an das Projekt zurücksenden.

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 Themenzweig erstellen, den Code ändern und schließlich diese Änderung wieder auf GitHub übertragen.

$ 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 'three seconds is better' (5)
[slow-blink 5ca509d] three seconds is better
 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 unsere 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 übernehmen (engl. commit) unsere Änderung in den Themen-Branch

  6. Wir pushen Sie unseren neuen Themen-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 Themenzweig gepusht haben und zeigt uns einen großen grünen Button, um unsere Änderungen zu überprüfen und einen Pull Request zum ursprünglichen Projekt zu öffnen.

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

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

Wenn wir auf die grüne Schaltfläche klicken, sehen wir einen Bildschirm, auf dem Sie aufgefordert werden, Ihrem Pull Request einen Titel und eine Beschreibung zu geben. Es ist fast immer sinnvoll, sich ein bisschen Mühe zu geben, da eine gute Beschreibung dem Eigentümer des ursprünglichen Projekts hilft, festzustellen, was Sie versucht haben, ob Ihre vorgeschlagenen Änderungen korrekt sind und ob die Annahme der Änderungen das ursprüngliche Projekt verbessern würde.

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

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

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

Note

Pull-Requests werden zwar häufig für öffentliche Projekte wie dieses verwendet, wenn der Beitragende eine vollständige Änderung fertig hat, sie werden jedoch auch zu Beginn des Entwicklungszyklus in internen Projekten verwendet. Da Sie den Themenzweig auch nach dem Öffnen des Pull-Requests weiter bearbeiten können, wird er oft früh geöffnet und als Möglichkeit genutzt, 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 vereinheitliche Diff überprüfen und einen Kommentar hinterlassen, indem er auf eine der Zeilen klickt.

Pull-Request Zeilen-Kommentar
Figure 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
Figure 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. Sie sehen, dass auch die Code-Kommentare in das Diskussionsfenster eingebracht werden.

Pull Request Diskussions-Seite
Figure 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 Sie über E-Mail Ihre Daten erneut in die Mailingliste eintragen müssen, committen Sie mit GitHub einfach erneut in den Themen-Branch und pushen, wodurch der Pull-Request automatisch aktualisiert wird. Im finalen Pull-Request sehen Sie auch, dass der alte Code-Kommentar in dem aktualisierten Pull-Request zusammengeklappt wurde, da er auf eine inzwischen geänderte Zeile gemacht wurde.

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
Figure 95. finaler Pull-Request

Eine bemerkenswerte Besonderheit ist, dass Sie den „vereinheitlichten“ Diff erhalten, wenn Sie auf die Registerkarte „Files Changed“ in diesem Pull-Request klicken – d.h. die gesamte aggregierte Differenz, die in Ihren Hauptbranch eingebracht würde, wenn dieser Themenzweig gemergt würde. Im Sinne von git diff zeigt es Ihnen 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 Diff.

Außerdem prüft GitHub, ob der Pull-Request sauber mergen würde und stellt eine Schaltfläche zur Verfügung, mit der Sie den Merge auf dem Server durchführen können. Diese Schaltfläche erscheint nur, wenn Sie Schreibzugriff auf das Repository haben und ein trivialer Merge möglich ist. Wenn Sie darauf klicken, 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 Sie möchten, können Sie den Branch einfach herunterladen (engl. pull) und lokal zusammenführen (engl. merge). Wenn Sie diesen Zweig mit dem master Branch verschmelzen und ihn nach GitHub pushen, wird der Pull Request automatisch geschlossen.

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

Note
Nicht nur Forks

Es ist wichtig zu erwähnen, dass Sie auch einen Pull-Request zwischen zwei Zweigen im selben Repository öffnen können. Wenn Sie mit jemandem an einer Funktion arbeiten und beide Schreibrechte auf das Projekt haben, können Sie einen Themenzweig 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 Ihnen einige interessante Tipps und Tricks zu Pull-Requests geben, damit Sie diese effektiver nutzen können.

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, wobei die meisten Mailinglisten-basierten Projekte an Patch-Serienbeiträge denken. Die meisten GitHub-Projekte betrachten Pull-Request-Branches als iterative Dialoge um eine beabsichtigte Änderung, die zu einem vereinheitlichten Diff führt, welches durch das Mergen angewendet wird.

Das ist ein wichtiger Unterschied, denn im Allgemeinen wird die Änderung vorgeschlagen, bevor der Code perfektioniert ist, was bei Beiträgen von Patch-Serien auf Mailinglistenbasis weitaus seltener ist. So kann früher mit den Betreuern gesprochen werden, damit die richtige Lösung eher eine Gemeinschaftsarbeit ist. 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, sondern der Unterschied wird als neuer Commit an den Branch weitergegeben (gepusht), wodurch der Dialog im intakten Kontext der vorherigen Arbeit fortgesetzt wird.

Wenn Sie beispielsweise zurückgehen und sich den finalen Pull-Request erneut ansehen, werden Sie feststellen, dass der Beitragende seinen Commit nicht umbasiert hat (engl. rebase) und einen weiteren Pull-Request geöffnet hat. Stattdessen wurden neue Commits hinzugefügt und sie in den bestehenden Zweig gepusht. Wenn Sie also in Zukunft auf diesen Pull Request zurückblicken, können Sie leicht den gesamten Kontext finden, in dem die Entscheidungen getroffen wurden. Wenn Sie auf der Website auf die Schaltfläche „Merge“ klicken, wird gezielt ein Merge-Commit erstellt, der auf den Pull-Request verweist, so dass Sie leicht zurückkehren und bei Bedarf die ursprüngliche Diskussion durchsuchen können.

Mit dem Upstream Schritt halten

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

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

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

Sie haben zwei grundsätzliche Möglichkeiten, wie Sie das realisieren können. Sie können Ihren Branch entweder auf den Ziel-Branch rebasen (normalerweise den master-Branch des von Ihnen geforkten Repositorys), oder Sie können den Ziel-Branch mit Ihrem 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 Sie im Ziel-Branch mergen wollen, um Ihren Pull-Request zusammenzuführen zu können, sollten Sie das ursprüngliche Repository als neuen Remote hinzufügen. Dann machen Sie ein git fetch davon, führen den Hauptzweig dieses Repositorys in Ihren Themen-Branch zusammen, beheben alle Probleme und pushen Sie es schließlich wieder in den gleichen Branch, in dem Sie den Pull-Request geöffnet hatten.

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 Themen-Branch mergen.

  4. Den aufgetretenen Konflikt beheben

  5. Zum gleichen Themen-Branch zurück pushen

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

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

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

Wenn Sie den Branch unbedingt rebasen wollen, um ihn aufzuräumen, können Sie das natürlich tun, aber es wird dringend empfohlen, den Branch, auf dem der Pull-Request bereits geöffnet ist, nicht zwangsweise zu 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. Schieben Sie stattdessen den rebasierten Branch zu einem neuen Branch auf GitHub und öffnen Sie einen brandneuen Pull Request mit Bezug auf den alten Branch und schließen Sie dann das Original.

Referenzen

Möglicherweise lautet Ihre 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 Sie auf einen Pull-Request oder ein Issue von einem anderen verweisen möchten, können Sie einfach #<num> in einen Kommentar oder eine Beschreibung eingeben. Sie können auch präziser sein, wenn die Issue- oder Pull-Anforderung an einem anderen Ort liegt; schreiben Sie Benutzername#<num>, wenn Sie sich auf ein Issue oder Pull Request beziehen, in einen Fork des Repositories, in dem Sie sich befinden, oder 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 rebasiert, 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 in der 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
Figure 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
Figure 99. Querverweise, die in einem Pull-Request erzeugt wurden

Bitte beachten Sie, 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
Figure 100. Zurück zum neuen Pull-Request in der geschlossenen Pull-Request Zeitleiste

Zusätzlich zu den Issue-Nummern können Sie auch auf einen bestimmten Commit per SHA-1 referenzieren. Sie müssen einen vollen 40-stelligen SHA-1 angeben, aber wenn GitHub das in einem Kommentar sieht, wird er direkt auf den Commit verlinken. Wie bei Issues können Sie 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 Sie mit fast jeder Textbox auf GitHub machen können. In Issue- und Pull-Request-Beschreibungen, Kommentaren, Code-Kommentaren und mehr, können Sie das sogenannte „GitHub Flavored Markdown“ verwenden. Markdown fühlt sich an wie das Schreiben in Klartext, hat aber umfangreiche Dargestellungs-Optionen.

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

Example Markdown
Figure 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 Sie hilfreiche Pull-Request, Issue-Kommentare oder Beschreibungen erstellen.

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 Sie erledigen möchten. Wenn Sie sie in einen Issue oder Pull-Request einfügen, werden normalerweise Punkte angezeigt, die Sie erledigen sollten, bevor Sie den Vorgang als erledigt betrachten.

Sie können 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
Figure 102. Aufgabenliste in Markdown-Kommentar, gerendert

Diese Funktion wird häufig in Pull Requests verwendet, um zu verdeutlichen, was alles Sie auf dem Branch erledigen möchten, bevor der Pull Request bereit für die Zusammenführung ist. Der wirklich coole Teil ist, dass Sie einfach auf die Kontrollkästchen klicken können, um den Kommentar zu aktualisieren – Sie müssen den Markdown nicht direkt bearbeiten, um Aufgaben abzuwählen.

Darüber hinaus sucht GitHub nach Aufgabenlisten in Ihren Issues und Pull Requests und sie als Metadaten auf den aufgelisteten Seiten anzeigt. Wenn Sie z.B. einen Pull-Request mit Aufgabenliste haben und sich die Übersichtsseite aller Pull-Requests ansehen, können Sie sehen, wie weit er abgearbeitet ist. Das hilft den Teilnehmern, Pull-Requests in Teilaufgaben aufzuschlüsseln und anderen Teilnehmern, den Fortschritt der Branch zu verfolgen. Ein Beispiel dafür finden Sie bei: Task-Liste (Zusammenfassung) in der Pull-Request-Liste.

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

Diese Funktion ist unglaublich nützlich, wenn Sie einen Pull Request frühzeitig öffnen und damit Ihren Fortschritt bei der Realisierung des Features verfolgen (engl. track).

Code-Schnipsel

Sie können auch Code-Schnipsel zu Kommentaren hinzufügen. Es ist dann besonders praktisch, wenn Sie etwas präsentieren möchten, das Sie versuchen könnten, bevor Sie es tatsächlich als Commit auf Ihrem Branch einbauen. 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, müssen Sie ihn in zwei 3-fach Backticks (```) „einzäunen“.

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

Wenn Sie den Namen der Programmiersprache hinzufügen, 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
Figure 104. „eingezäuntes“, gerendertes Code-Schnipsel-Beispiel

Quoten (Zitieren)

Wenn Sie auf einen kleinen Teil eines langen Kommentars reagieren wollen, können Sie selektiv aus dem anderen Kommentar zitieren, indem Sie den Zeilen das Zeichen > voranstellen. Es ist sogar so häufig und nützlich, dass es eine Tastenkombination dafür gibt. Wenn Sie Text in einem Kommentar markieren, auf den Sie direkt antworten möchten, und die Taste r drücken, wird dieser Text in der Kommentarbox für Sie 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: gerenderes Zitat-Beispiel..

Rendered quoting
Figure 105. gerenderes Zitat-Beispiel.

Emojis

Abschließend, Sie können auch Emojis in Ihren Kommentaren verwenden. Das wird in der Praxis sehr häufig in Kommentaren verwendet, die Sie es bei vielen GitHub-Issues und Pull-Requests sehen. Es gibt sogar einen Emoji-Helfer in GitHub. Wenn Sie einen Kommentar eingeben und mit einem : (Doppelpunkt) beginnen, hilft Ihnen ein Autokomplettierer, das Gesuchte schnell zu finden.

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

Emojis haben die Erscheinungsform von :<name>: irgendwo im Kommentar. Zum Beispiel könnten Sie so ähnlich wie hier 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
Figure 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.

Note

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 Sie sagen wollen, finden Sie unter:

Bilder

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

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

Wenn Sie sich Bilder per Drag&Drop hochladen und automatisch einbetten ansehen, werden Sie einen kleinen Hinweis, „Parsed as Markdown“, über dem Textfeld sehen. Wenn Sie darauf klicken, erhalten Sie einen vollständigen Cheat-Sheet (Spickzettel) mit allem, was Sie mit Markdown auf GitHub machen können.

Ihr öffentliches GitHub-Repository aktuell halten

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

This branch is 5 commits behind progit:master.

Aber Ihr GitHub-Repository wird nie automatisch von GitHub aktualisiert; das ist etwas, was Sie selbst tun müssen. Glücklicherweise ist das sehr einfach umzusetzen.

Die eine Möglichkeit erfordert keine Konfiguration. Wenn Sie z.B. von https://github.com/progit/progit2.git geforkt haben, können Sie Ihren 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 Sie sich in einem anderen Branch befinden, kehren Sie zu master zurück.

  2. Holen (engl. fetch) Sie sich Änderungen von https://github.com/progit/progit2.git und mergen Sie sie in den master.

  3. Pushen Sie Ihren master Branch nach origin.

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

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

  2. Konfigurieren Sie Ihren master Branch so, dass er von dem progit Remote abgeholt (engl. fetch) wird.

  3. Definieren Sie 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 Sie sich in einem anderen Branch befinden, kehren Sie zu master zurück.

  2. Fetchen Sie die Änderungen von progit und mergen Sie sie in master.

  3. Pushen Sie Ihren 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 Sie erledigen, aber es wird Sie nicht benachrichtigen, wenn Sie einen Commit zum master machen, von progit pullen und dann zu origin pushen – alle diese Operationen sind mit diesem Setup zulässig. Sie müssen also darauf achten, nie direkt an den master zu committen, da dieser Branch faktisch zum Upstream-Repository gehört.