pixel
Select Page

Divide and Conquer – Verteilte Git-Konfiguration

by | Jul 21, 2022 | Development, DevOps, GitLab

In meinem zehnten Monat als Consultant bei NETWAYS angekommen, bin ich inzwischen gut in verschiedenste Kundenprojekte integriert. Das sorgt einerseits für einen abwechslungsreichen Alltag mit immer neuen Herausforderungen, andererseits stellte sich irgendwann ein grundlegendes Problem heraus: Ich kann nicht jonglieren!

Dabei wäre das bei der Vielzahl an geschäftlichen Email-Adressen, SSH- und GPG-Schlüsseln und anderen Kleinigkeiten, die sich von Kunde zu Kunde, Plattform zu Plattform und Projekt zu Projekt unterscheiden, dringend notwendig. Ein unsignierter Commit mit falscher Email auf Github, Gitlab oder sonstiger Plattform ist da bei meinem Talent für Schusseligkeit nur eine Frage der Zeit. Glücklicherweise gibt es ein Git-Feature, das hier unterstützen kann: Die hierarchische Einbindung mehrerer .gitconfig Dateien.

Theorie und Möglichkeiten

Standardmäßig liest git die hinterlegte Konfiguration laut offizieller Dokumentation aus vier Verzeichnissen/Dateien aus:

  • $(prefix)/etc/gitconfig – der systemweiten Git-Konfiguration
  • $XDG_CONFIG_HOME – einer userspezifischen Git-Konfiguration, oftmals unter $HOME/.config/git
  • ~/.gitconfig – einer weiteren userspezifischen Git-Konfiguration, auch “globale Git-Konfiguration” genannt
  • $GIT_DIR/config – einer Git-Konfiguration auf Repositoryebene

Die Dateien werden hierbei von jeder Routine, die auf git-Konfiguration zurückgreift, in obiger Reihenfolge ausgelesen, bei mehrfach definierten Werten greift hierbei der letzte, sodass ein “Feintuning” von globaler Konfiguration hin zu projektspezifischen Einstellungen im Repository schon einmal möglich ist. Für noch bessere Verteilung und optionale Einbindung von erweiternder Konfiguration gibt Git Dir eine praktische Direktive an die Hand: includeIf.

Sie erlaubt es Dir, optional Konfiguration von beliebigen Stellen in die gerade betrachtete Datei einzubinden – die dort hinterlegten Einstellungen werden also zeitgleich evaluiert. Für eine bessere Kontrolle darüber, wann zusätzliche Einstellungen importiert werden sollen, können wir uns erneut die Dokumentation von git, genauer gesagt den Abschnitt zu Conditional Includes anschauen, denn hier gibt es verschiedene Optionen:

  • gitdir – die Einbindung erfolgt, wenn die Auswertung (via Befehl, Script, etc.) der Git-Konfiguration aus einem der Angabe entsprechenden (Unter-)Verzeichnis erfolgt. gitdir unterstützt Wildcards und Case(in)sensitivity.
  • onbranch – die Einbindung erfolgt aus einem momentan ausgecheckten Branch erfolgt, der der Angabe entspricht. Wildcards und Case(in)sensitivity werden auch hier unterstützt
  • hasconfig:remote.*.url – die Schreibweise ist etwas gewöhnungsbedürftig und auch die Anwendungsmöglichkeiten nicht so geradlinig wie bei den anderen Optionen: Hierbei werden optional Einstellungen eingebunden, wenn sich irgendwo in der lokalen Git-Konfiguration (nicht zwingend in der gleichen betrachteten Datei) eine remote URL findet, die der Angabe entspricht. Das ist bspw. nützlich, um mehrere Repositories mit bestimmter, immer gleicher Konfiguration zu versehen  (z.B. alle Repositories, die Icingaweb2-Module bereitstellen)

Praxis

Doch wie kann so etwas in der Praxis aussehen? Wie eingangs erwähnt, war mir vor Allem die Handhabe mehrerer kundenbezogener Email-Adressen und damit verknüpfter GPG-Schlüssel zu lästig, sodass ich hier für die Konfiguration zu einem hierarchischen Ansatz zurückgriff. Meine globale Git-Konfiguration unter ~/.gitconfig gestaltete ich also wie folgt:

Screenshot einer globalen Gitkonfiguration

Globale Gitkonfiguration unter ~/.gitconfig

Neben “Standardeinstellungen” wie meinem im Commit zu setzenden Namen, der Defaultbranch bei der Erstellung neuer Repositories, die Anweisung, Commits immer mittels GPG zu signieren und das dafür zu nutzende Programm finden sich hier vier includeIf-Abschnitte.

Diese decken die verschiedenen Unterverzeichnisse meines Entwicklungsverzeichnisses ~/repositories/ ab – die trailing Slashes am Ende der jeweiligen Pfaddefinition sorgen dafür, dass die jeweiligen Unterverzeichnisse rekursiv gematcht werden. Im Beispiel hieße das, dass sowohl ein Repository unter ~/repositories/netways/blogpost_dbodky als auch ein Repository unter ~/repositories/netways/icinga-related/director-patches die zusätzlichen Git-Einstellungen unter ~/repositories/netways/.gitconfig einbinden würde.

In den in meiner globalen Git-Konfiguration referenzierten optional einzubindenden Dateien finden sich dann die Kunden- oder projektspezifischen Einstellungen für Git – das können mal mehr, mal weniger sein, um das Beispiel einfach zu halten hier die minimalistische Version für meine privaten Repositories, in der ich nur meine private Emailadresse sowie den damit verknüpften GPG-Schlüssel für die Signierung angebe:

Screenshot einer spezifischen Gitkonfiguration unter ~/repositories/private/.gitconfig

Spezifische Gitkonfiguration unter ~/repositories/private/.gitconfig

Was ihr jetzt in eure Gitkonfigurationen einbauen möchtet und wie ihr sie strukturiert, ist komplett euch überlassen – Git macht hierbei keine Vorschriften sondern arbeitet stur die vier eingangs erwähnten Dateien und alle optional einzubindenden Verzeichnisse und Dateien ab. Wichtig ist lediglich die Reihenfolge der Angaben, da sich diese gegebenenfalls überschreiben können.

Falls Du diesen Blogpost interessant fandest, aber bei Git noch Steigerungsbedarf siehst oder bei der Erwähnung von remote URLs ausgestiegen bist, kann ich Dir an dieser Stelle die NETWAYS Gitlab Schulung ans Herz legen, wo Du in Sachen Versionsverwaltung und DevOps voll durchstarten kannst.

Daniel Bodky
Daniel Bodky
Consultant

Daniel kam nach Abschluss seines Studiums im Oktober 2021 zu NETWAYS und berät nun Kunden zu den Themen Icinga2 und Kubernetes. Nebenher schreibt er in seiner Freizeit kleinere Tools für verschiedenste Einsatzgebiete, nimmt öfters mal ein Buch in die Hand oder widmet sich seinem viel zu großen Berg Lego. In der wärmeren Jahreszeit findet man ihn außerdem oft auf dem Fahrrad oder beim Wandern.
More posts on the topic Development | DevOps | GitLab

Ansible – Testing roles with Molecule

Ansible is a widely used and a powerful open-source configuration and deployment management tool. It can be used for simple repetitive daily tasks or complex application deployments, therefore Ansible is able to cover mostly any situation. If used in complex or...

NETWAYS Support Collector Roadmap

Den Support Collector konnte ich bereits in meinem letzten Blogpost vorstellen. Für alle die den Beitrag verpasst haben, hier kurz umrissen was es ist: Bei dem Tool handelt es sich um einen von uns geschriebenen Datensammler, welche alle möglichen Support relevanten...

HUGO: GitLab-CI/CD-Pipeline für eine statische Website

Vor etwa 4 Monaten habe ich hier einen Blogpost geschrieben, in dem ich Hugo vorgestellt habe - eine Software zum Generieren statischer Webseiten aus Markdown-Dateien. Im Lauf meiner Ausbildung zum Fachinformatiker für Systemintegration bei NETWAYS habe ich vor kurzem...

DockerCon 2022: Wie geht Containersecurity?

Buzzwords wie Software Supply Chain, Container Security Scanning oder Software Bill of Materials (SBOM) sind in den vergangenen zwei Jahren vermehrt in aller Munde, nicht zuletzt aufgrund des anhaltenden Trends zur Containerisierung vormals monolithischer Anwendungen...