-
1. Erste Schritte
- 1.1 Über Versionskontrolle
- 1.2 Eine kurze Geschichte von Git
- 1.3 Was ist Git?
- 1.4 Die Kommandozeile
- 1.5 Git installieren
- 1.6 Erstmalige Git-Einrichtung
- 1.7 Hilfe bekommen
- 1.8 Zusammenfassung
-
2. Git Grundlagen
-
3. Git Branching
- 3.1 Branches im Überblick
- 3.2 Grundlegendes Branching und Merging
- 3.3 Branch-Management
- 3.4 Branching-Workflows
- 3.5 Remote-Branches
- 3.6 Rebasing
- 3.7 Zusammenfassung
-
4. Git auf dem Server
- 4.1 Die Protokolle
- 4.2 Git auf einem Server einrichten
- 4.3 Generieren Ihres SSH-Public-Keys
- 4.4 Einrichten des Servers
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Drittanbieter-Hosting-Optionen
- 4.10 Zusammenfassung
-
5. Verteiltes Git
-
6. GitHub
-
7. Git-Werkzeuge
- 7.1 Revisionsauswahl
- 7.2 Interaktives Staging
- 7.3 Stashing und Bereinigen
- 7.4 Ihre Arbeit signieren
- 7.5 Suchen
- 7.6 Historie umschreiben
- 7.7 Reset entmystifiziert
- 7.8 Fortgeschrittenes Merging
- 7.9 Rerere
- 7.10 Debugging mit Git
- 7.11 Submodule
- 7.12 Bundling
- 7.13 Ersetzen
- 7.14 Credential-Speicher
- 7.15 Zusammenfassung
-
8. Git anpassen
-
9. Git und andere Systeme
- 9.1 Git als Client
- 9.2 Migration zu Git
- 9.3 Zusammenfassung
-
10. Git-Interna
- 10.1 Plumbing und Porcelain
- 10.2 Git-Objekte
- 10.3 Git-Referenzen
- 10.4 Packfiles
- 10.5 Die Refspec
- 10.6 Übertragungsprotokolle
- 10.7 Wartung und Datenwiederherstellung
- 10.8 Umgebungsvariablen
- 10.9 Zusammenfassung
-
Anhang A: Git in anderen Umgebungen
- A1.1 Grafische Oberflächen
- A1.2 Git in Visual Studio
- A1.3 Git in Visual Studio Code
- A1.4 Git in IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git in Sublime Text
- A1.6 Git in Bash
- A1.7 Git in Zsh
- A1.8 Git in PowerShell
- A1.9 Zusammenfassung
-
Anhang B: Git in Ihre Anwendungen einbetten
- A2.1 Kommandozeilen-Git
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
Anhang C: Git-Befehle
- A3.1 Einrichtung und Konfiguration
- A3.2 Projekte abrufen und erstellen
- A3.3 Grundlegendes Snapshotting
- A3.4 Branching und Merging
- A3.5 Projekte teilen und aktualisieren
- A3.6 Inspektion und Vergleich
- A3.7 Debugging
- A3.8 Patching
- A3.9 E-Mail
- A3.10 Externe Systeme
- A3.11 Administration
- A3.12 Plumbing-Befehle
6.5 GitHub - GitHub-Scripting
GitHub-Scripting
Wir haben nun alle wichtigen Funktionen und Workflows von GitHub behandelt, aber jede größere Gruppe oder jedes Projekt wird Anpassungen haben, die sie vornehmen möchten, oder externe Dienste, die sie integrieren möchten.
Glücklicherweise ist GitHub in vielerlei Hinsicht sehr gut erweiterbar. In diesem Abschnitt werden wir behandeln, wie Sie das GitHub-Hooks-System und seine API nutzen können, um GitHub so zu gestalten, wie wir es wünschen.
Dienste und Hooks
Der Abschnitt "Hooks und Dienste" in der GitHub-Repository-Administration ist der einfachste Weg, damit GitHub mit externen Systemen interagiert.
Dienste
Zuerst werfen wir einen Blick auf Dienste. Sowohl die Hooks- als auch die Dienste-Integrationen finden Sie im Einstellungsbereich Ihres Repositorys, wo wir zuvor das Hinzufügen von Mitwirkenden und das Ändern des Standard-Branches Ihres Projekts besprochen haben. Unter dem Reiter "Webhooks und Dienste" sehen Sie etwas wie den Konfigurationsbereich für Dienste und Hooks.
Es gibt Dutzende von Diensten, aus denen Sie wählen können, die meisten davon sind Integrationen in andere kommerzielle und Open-Source-Systeme. Die meisten davon sind für Continuous-Integration-Dienste, Bug- und Issue-Tracker, Chatraum-Systeme und Dokumentationssysteme. Wir werden die Einrichtung eines sehr einfachen Dienstes, des E-Mail-Hooks, durchgehen. Wenn Sie "E-Mail" aus dem Dropdown-Menü "Dienst hinzufügen" auswählen, erhalten Sie einen Konfigurationsbildschirm wie die E-Mail-Dienstkonfiguration.
In diesem Fall wird die angegebene E-Mail-Adresse jedes Mal eine E-Mail erhalten, wenn jemand einen Push im Repository durchführt, wenn wir auf die Schaltfläche "Dienst hinzufügen" klicken. Dienste können auf viele verschiedene Arten von Ereignissen reagieren, aber die meisten reagieren nur auf Push-Ereignisse und tun dann etwas mit diesen Daten.
Wenn es ein System gibt, das Sie verwenden und mit GitHub integrieren möchten, sollten Sie hier nachsehen, ob eine vorhandene Diensteintegration verfügbar ist. Wenn Sie beispielsweise Jenkins verwenden, um Tests für Ihren Code auszuführen, können Sie die integrierte Jenkins-Diensteintegration aktivieren, um jedes Mal, wenn jemand einen Push in Ihr Repository durchführt, einen Testlauf zu starten.
Hooks
Wenn Sie etwas Spezifischeres benötigen oder eine Verbindung zu einem Dienst oder einer Website herstellen möchten, die nicht in dieser Liste enthalten ist, können Sie stattdessen das allgemeinere Hooks-System verwenden. GitHub-Repository-Hooks sind ziemlich einfach. Sie geben eine URL an und GitHub sendet eine HTTP-Payload an diese URL bei jedem von Ihnen gewünschten Ereignis.
Im Allgemeinen richten Sie einen kleinen Webdienst ein, der auf eine GitHub-Hook-Payload hört und dann etwas mit den empfangenen Daten tut.
Um einen Hook zu aktivieren, klicken Sie im Bereich Konfiguration von Diensten und Hooks auf die Schaltfläche "Webhook hinzufügen". Daraufhin gelangen Sie zu einer Seite, die wie die Webhook-Konfiguration aussieht.
Die Konfiguration eines Webhooks ist ziemlich einfach. In den meisten Fällen geben Sie einfach eine URL und einen geheimen Schlüssel ein und klicken auf "Webhook hinzufügen". Es gibt einige Optionen, für welche Ereignisse GitHub Ihnen eine Payload senden soll – standardmäßig erhalten Sie nur eine Payload für das `push`-Ereignis, wenn jemand neuen Code in einen beliebigen Branch Ihres Repositorys pusht.
Sehen wir uns ein kleines Beispiel für einen Webdienst an, den Sie zur Verarbeitung eines Webhooks einrichten könnten. Wir verwenden das Ruby-Webframework Sinatra, da es ziemlich prägnant ist und Sie leicht nachvollziehen können, was wir tun.
Nehmen wir an, wir möchten eine E-Mail erhalten, wenn eine bestimmte Person einen Push in einen bestimmten Branch unseres Projekts durchführt, der eine bestimmte Datei modifiziert. Das könnten wir ziemlich einfach mit Code wie diesem tun.
require 'sinatra'
require 'json'
require 'mail'
post '/payload' do
push = JSON.parse(request.body.read) # parse the JSON
# gather the data we're looking for
pusher = push["pusher"]["name"]
branch = push["ref"]
# get a list of all the files touched
files = push["commits"].map do |commit|
commit['added'] + commit['modified'] + commit['removed']
end
files = files.flatten.uniq
# check for our criteria
if pusher == 'schacon' &&
branch == 'ref/heads/special-branch' &&
files.include?('special-file.txt')
Mail.deliver do
from 'tchacon@example.com'
to 'tchacon@example.com'
subject 'Scott Changed the File'
body "ALARM"
end
end
end
Hier nehmen wir die JSON-Payload, die GitHub uns liefert, und suchen heraus, wer sie gepusht hat, auf welchen Branch er gepusht hat und welche Dateien in allen Commits berührt wurden, die gepusht wurden. Dann überprüfen wir dies anhand unserer Kriterien und senden eine E-Mail, wenn es übereinstimmt.
Um so etwas zu entwickeln und zu testen, gibt es in derselben Ansicht, in der Sie den Hook einrichten, eine nützliche Entwicklerkonsole. Sie können die letzten Zustellungen sehen, die GitHub für diesen Webhook versucht hat. Für jeden Hook können Sie detailliert nachsehen, wann er zugestellt wurde, ob er erfolgreich war, sowie den Body und die Header für Anfrage und Antwort. Dies macht das Testen und Debuggen Ihrer Hooks unglaublich einfach.
Das andere großartige Merkmal hierbei ist, dass Sie jede der Payloads erneut zustellen können, um Ihren Dienst einfach zu testen.
Weitere Informationen darüber, wie man Webhooks schreibt und welche verschiedenen Ereignistypen man abhören kann, finden Sie in der GitHub-Entwicklerdokumentation unter https://docs.github.com/en/webhooks-and-events/webhooks/about-webhooks.
Die GitHub-API
Dienste und Hooks geben Ihnen eine Möglichkeit, Push-Benachrichtigungen über Ereignisse zu erhalten, die in Ihren Repositorys stattfinden, aber was, wenn Sie mehr Informationen über diese Ereignisse benötigen? Was, wenn Sie etwas automatisieren müssen, wie z.B. das Hinzufügen von Mitwirkenden oder das Markieren von Issues?
Hier kommt die GitHub-API ins Spiel. GitHub hat unzählige API-Endpunkte, um fast alles, was Sie auf der Website tun können, auf automatisierte Weise zu erledigen. In diesem Abschnitt lernen wir, wie man sich authentifiziert und mit der API verbindet, wie man einen Kommentar zu einem Issue abgibt und wie man den Status eines Pull Requests über die API ändert.
Grundlegende Nutzung
Das grundlegendste, was Sie tun können, ist eine einfache GET-Anfrage an einen Endpunkt, der keine Authentifizierung erfordert. Dies könnten Benutzer- oder Leseinformationen zu einem Open-Source-Projekt sein. Wenn wir beispielsweise mehr über einen Benutzer namens "schacon" erfahren möchten, können wir Folgendes ausführen:
$ curl https://api.github.com/users/schacon
{
"login": "schacon",
"id": 70,
"avatar_url": "https://avatars.githubusercontent.com/u/70",
# …
"name": "Scott Chacon",
"company": "GitHub",
"following": 19,
"created_at": "2008-01-27T17:19:28Z",
"updated_at": "2014-06-10T02:37:23Z"
}
Es gibt unzählige Endpunkte wie diesen, um Informationen über Organisationen, Projekte, Issues, Commits abzurufen – so ziemlich alles, was Sie öffentlich auf GitHub sehen können. Sie können die API sogar verwenden, um beliebigen Markdown zu rendern oder eine `.gitignore`-Vorlage zu finden.
$ curl https://api.github.com/gitignore/templates/Java
{
"name": "Java",
"source": "*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see https://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
"
}
Kommentieren eines Issues
Wenn Sie jedoch eine Aktion auf der Website ausführen möchten, wie z.B. einen Kommentar zu einem Issue oder Pull Request abgeben, oder wenn Sie private Inhalte anzeigen oder mit ihnen interagieren möchten, müssen Sie sich authentifizieren.
Es gibt mehrere Möglichkeiten zur Authentifizierung. Sie können die Basisauthentifizierung mit Ihrem Benutzernamen und Passwort verwenden, aber im Allgemeinen ist es besser, ein persönliches Zugriffstoken zu verwenden. Sie können dieses im Reiter "Anwendungen" auf Ihrer Einstellungsseite generieren.
Es wird Sie nach den gewünschten Bereichen für dieses Token und einer Beschreibung fragen. Verwenden Sie eine gute Beschreibung, damit Sie das Token beruhigt entfernen können, wenn Ihr Skript oder Ihre Anwendung nicht mehr verwendet wird.
GitHub zeigt Ihnen das Token nur einmal an, stellen Sie also sicher, dass Sie es kopieren. Sie können es nun anstelle von Benutzername und Passwort zur Authentifizierung in Ihrem Skript verwenden. Das ist praktisch, da Sie den Umfang Ihrer Aktionen einschränken können und das Token widerrufbar ist.
Dies hat auch den zusätzlichen Vorteil, dass Ihr Ratenlimit erhöht wird. Ohne Authentifizierung sind Sie auf 60 Anfragen pro Stunde beschränkt. Wenn Sie sich authentifizieren, können Sie bis zu 5.000 Anfragen pro Stunde stellen.
Verwenden wir es also, um einen Kommentar zu einem unserer Issues zu hinterlassen. Nehmen wir an, wir möchten einen Kommentar zu Issue #6 hinterlassen. Dazu müssen wir eine HTTP-POST-Anfrage an `repos/
$ curl -H "Content-Type: application/json" \
-H "Authorization: token TOKEN" \
--data '{"body":"A new comment, :+1:"}' \
https://api.github.com/repos/schacon/blink/issues/6/comments
{
"id": 58322100,
"html_url": "https://github.com/schacon/blink/issues/6#issuecomment-58322100",
...
"user": {
"login": "tonychacon",
"id": 7874698,
"avatar_url": "https://avatars.githubusercontent.com/u/7874698?v=2",
"type": "User",
},
"created_at": "2014-10-08T07:48:19Z",
"updated_at": "2014-10-08T07:48:19Z",
"body": "A new comment, :+1:"
}
Wenn Sie nun zu diesem Issue gehen, können Sie den Kommentar sehen, den wir gerade erfolgreich gepostet haben, wie in Ein Kommentar vom GitHub API gepostet.
Sie können die API nutzen, um fast alles zu tun, was Sie auf der Website tun können – Erstellen und Festlegen von Meilensteinen, Zuweisen von Personen zu Issues und Pull Requests, Erstellen und Ändern von Labels, Zugriff auf Commit-Daten, Erstellen neuer Commits und Branches, Öffnen, Schließen oder Mergen von Pull Requests, Erstellen und Bearbeiten von Teams, Kommentieren von Codezeilen in einem Pull Request, Suchen auf der Website und so weiter.
Ändern des Status eines Pull Requests
Es gibt ein letztes Beispiel, das wir uns ansehen werden, da es bei der Arbeit mit Pull Requests sehr nützlich ist. Jeder Commit kann einen oder mehrere zugehörige Status haben und es gibt eine API, um diesen Status hinzuzufügen und abzufragen.
Die meisten Continuous-Integration- und Testdienste nutzen diese API, um auf Pushes zu reagieren, indem sie den gepushten Code testen und dann zurückmelden, ob der Commit alle Tests bestanden hat. Sie könnten dies auch verwenden, um zu überprüfen, ob die Commit-Nachricht richtig formatiert ist, ob der Einreicher alle Ihre Beitragsrichtlinien befolgt hat, ob der Commit gültig signiert wurde – eine beliebige Anzahl von Dingen.
Nehmen wir an, Sie richten einen Webhook in Ihrem Repository ein, der einen kleinen Webdienst aufruft, der nach einer `Signed-off-by`-Zeichenfolge in der Commit-Nachricht sucht.
require 'httparty'
require 'sinatra'
require 'json'
post '/payload' do
push = JSON.parse(request.body.read) # parse the JSON
repo_name = push['repository']['full_name']
# look through each commit message
push["commits"].each do |commit|
# look for a Signed-off-by string
if /Signed-off-by/.match commit['message']
state = 'success'
description = 'Successfully signed off!'
else
state = 'failure'
description = 'No signoff found.'
end
# post status to GitHub
sha = commit["id"]
status_url = "https://api.github.com/repos/#{repo_name}/statuses/#{sha}"
status = {
"state" => state,
"description" => description,
"target_url" => "http://example.com/how-to-signoff",
"context" => "validate/signoff"
}
HTTParty.post(status_url,
:body => status.to_json,
:headers => {
'Content-Type' => 'application/json',
'User-Agent' => 'tonychacon/signoff',
'Authorization' => "token #{ENV['TOKEN']}" }
)
end
end
Hoffentlich ist das recht einfach zu verstehen. In diesem Webhook-Handler durchsuchen wir jeden Commit, der gerade gepusht wurde, suchen nach der Zeichenfolge 'Signed-off-by' in der Commit-Nachricht und senden schließlich per HTTP POST an den API-Endpunkt `/repos/
In diesem Fall können Sie einen Zustand ('success', 'failure', 'error'), eine Beschreibung dessen, was passiert ist, eine Ziel-URL, zu der der Benutzer weitere Informationen finden kann, und einen "Kontext" senden, falls es mehrere Status für einen einzelnen Commit gibt. Beispielsweise kann ein Testdienst einen Status bereitstellen, und ein Validierungsdienst wie dieser kann ebenfalls einen Status bereitstellen – das Feld "Kontext" ist die Art und Weise, wie sie unterschieden werden.
Wenn jemand einen neuen Pull Request auf GitHub öffnet und dieser Hook eingerichtet ist, sehen Sie möglicherweise etwas wie den Commit-Status über die API.
Sie sehen nun ein kleines grünes Häkchen neben dem Commit, dessen Nachricht eine Zeichenfolge "Signed-off-by" enthält, und ein rotes Kreuz bei dem, bei dem der Autor vergessen hat, sich abzumelden. Sie sehen auch, dass der Pull Request den Status des letzten Commits im Branch übernimmt und Sie warnt, wenn es ein Fehler ist. Dies ist sehr nützlich, wenn Sie diese API für Testergebnisse verwenden, damit Sie nicht versehentlich etwas mergen, bei dem der letzte Commit Tests fehlschlägt.
Octokit
Obwohl wir in diesen Beispielen fast alles über `curl` und einfache HTTP-Anfragen gemacht haben, gibt es mehrere Open-Source-Bibliotheken, die diese API auf idiomatischere Weise bereitstellen. Zum Zeitpunkt des Schreibens umfassen die unterstützten Sprachen Go, Objective-C, Ruby und .NET. Besuchen Sie https://github.com/octokit für weitere Informationen, da diese viel von der HTTP-Kommunikation für Sie übernehmen.
Hoffentlich helfen Ihnen diese Werkzeuge dabei, GitHub anzupassen und zu modifizieren, damit es für Ihre spezifischen Workflows besser funktioniert. Vollständige Dokumentationen zur gesamten API sowie Anleitungen für gängige Aufgaben finden Sie unter https://docs.github.com/.