3 Punkte von GN⁺ 2024-11-26 | 1 Kommentare | Auf WhatsApp teilen
  • In einer Umgebung, in der private und berufliche Repositories alle unter ~/workspace liegen, ist es genauer, Git-Identitäten anhand der remote URL statt anhand des Ordnerpfads zu trennen
  • Git kann mit includeIf per gitdir pfadabhängige Konfigurationen laden, aber wenn Repositories mehrerer Accounts im selben Arbeitsverzeichnis gemischt sind, stößt die pfadbasierte Verzweigung an ihre Grenzen
  • Mit der Bedingung hasconfig:remote.*.url: lassen sich separate Konfigurationsdateien anhand von remote-URL-Mustern einbinden, etwa für GitHub, GitLab, SourceHut oder eine bestimmte GitHub-Organisation
  • SSH-Keys müssen separat in ~/.ssh/config über Host, Hostname, User und IdentityFile verwaltet werden; wer selbst bei demselben github.com organisationsspezifische Keys verwenden will, braucht Host-Aliasse
  • Wenn zusätzlich url.<base>.insteadOf gesetzt wird, kann man wie gewohnt git@github.com:orgname/project verwenden, während Git dies intern durch gh-work:orgname ersetzt und so die richtige SSH-Konfiguration nutzt

Git-Konfiguration anhand der remote URL aufteilen

  • Gängige includeIf-Beispiele binden je nach lokalem Verzeichnispfad unterschiedliche Konfigurationsdateien ein, etwa gitdir:~/code/** oder gitdir:~/work/**
    • Unter ~/code lässt sich ~/.config/git/personal laden, unter ~/work dagegen ~/.config/git/work
    • Die eingebundenen Dateien enthalten normalerweise Git-Identität und Signaturschlüssel wie user.name, user.email und user.signingkey
  • Wenn sämtlicher Code unter ~/workspace liegt, können private Repositories sowie work-1- und work-2-Repositories in derselben Pfadstruktur gemischt sein; mit rein pfadbasierten Bedingungen ist die gewünschte Trennung dann schwierig
  • Mit Git hasconfig:remote.*.url: kann eine Konfigurationsdatei nur dann eingebunden werden, wenn das aktuelle Repository eine bestimmte remote URL enthält
    • Passt git@github.com:*/**, dann ~/.config/git/config-gh
    • Passt git@github.com:orgname/**, dann ~/.config/git/config-gh-org
    • Passt git@gitlab.com:*/**, dann ~/.config/git/config-gl
    • Passt git@git.sr.ht:*/**, dann ~/.config/git/config-srht
  • Da Git die zuletzt passende Konfiguration einbindet, ist die Reihenfolge der Bedingungen wichtig
    • Die Bedingung github.com:orgname/** muss unterhalb der allgemeinen Bedingung github.com:*/** stehen, damit die organisationsspezifische Konfiguration nicht von der allgemeinen GitHub-Konfiguration überschrieben wird
  • Im Ergebnis verwenden Repositories mit einem github.com:orgname/**-remote config-gh-org, während andere GitHub-Repositories die allgemeine GitHub-Konfiguration nutzen

SSH-Keys und insteadOf nutzen, um organisationsspezifische Verbindungsdaten zuzuordnen

1 Kommentare

 
GN⁺ 2024-11-26
Kommentare auf Hacker News
  • Statt insteadOf zu verwenden, klont man das Repository als gh-work:org/repo und setzt in der Git-Konfiguration includeIf "hasconfig:remote.*.url:gh-work:**/**"
    So übernehmen Repositories, die mit der unter gh-work definierten SSH-Identität geklont wurden, automatisch die Konfiguration aus gh-work.inc; darin stehen der Git-Identität entsprechende Signaturschlüssel und die SSH-Konfiguration
    Am Ende wird der Name gh-work zum Unterscheidungsmerkmal zwischen SSH-Identität und Git-Identität, was leichter verständlich ist

    • Die Lösung im Artikel wirkte etwas unangenehm, weil sie mehr Freiheitsgrade zu haben schien als nötig; das hier sieht nach einem eleganten Weg aus, die Laufzeitparameter auf einen zu reduzieren
    • includeIf ist case-sensitive, und bei der Priorität gewinnt die zuletzt gesetzte Konfiguration
      Um zu prüfen, ob es korrekt funktioniert, kann man git remote get-url origin und git config --get user.email ausführen
    • Dieser Ansatz konnte Skripte kaputtmachen, die erwarten, dass Remote-Repository-URLs eine bestimmte Form haben
  • Ich halte es für besser, in der .gitconfig unter HOME identitätsspezifische Aliasse zu hinterlegen und direkt nach dem Initialisieren oder Klonen eines Repositories git config-company oder git config-personal auszuführen
    Man aktiviert user.useConfigOnly = true und lässt die Aliasse im lokalen Repository user.email, user.name und core.sshCommand jeweils auf den privaten bzw. geschäftlichen SSH-Key setzen

    • Das Problem bleibt, wie man den ersten Clone ohne von Anfang an korrekte SSH-Konfiguration durchführt
      Der Vorteil der Methode aus dem Artikel scheint zu sein, dass es einfach funktioniert, wenn man aus der Organisation klont
  • Bei einem früheren Startup gab es jemanden, der seine Identität jeden Tag auf irgendeinen märchenhaften Namen änderte
    Montags-Commits waren von Mr. Bunnymann, Dienstags-Commits von Doctor Funtime und so weiter; das war bei Versionskontroll-Forensik extrem unpraktisch
    Wohlwollend betrachtet wollte er vielleicht daran erinnern, dass jeder beliebige Werte in die Identitätseinstellungen schreiben kann und man diesen Werten nicht zu sehr vertrauen sollte

    • In einer blameless culture wäre bei Versionskontroll-Forensik wichtiger gewesen, wann etwas passiert ist und in der Nähe welcher Änderungen, als wer es getan hat
      Trotzdem hilft es, zu wissen, wer es war, wenn man Details nachfragen oder Stil und Fachkenntnis einschätzen will
      Wenn man GPG-Signaturen für Commits verlangt und zulässige GPG-Identitäten registriert, kann man den tatsächlichen Autor über die Signatur statt über Autor-/Committer-Metadaten identifizieren
      Natürlich passen „einfach“ und GPG-Signaturen nicht immer gut zusammen
    • Man sollte dem genauso vertrauen wie Dokumenten oder Signaturen, die Mitarbeitende verfassen
      Wenn man Mitarbeitenden nicht zutraut, ihre eigenen Commits korrekt zu kennzeichnen, sollte man sie meiner Meinung nach entlassen
    • Wohlwollend betrachtet wäre ich neugierig, ob derselbe Signaturschlüssel verwendet wurde
    • Erstaunlich, dass jemand für solchen Unsinn bezahlt wurde
    • Git unterstützt die Trennung von Autor und Committer von Haus aus; vermutlich wurde nur das Author-Attribut geändert
  • Ohne ~/.ssh/config anzufassen, kann man in ~/.gitconfig oder wie im Artikel in ~/.config/git/personal core.sshCommand = /usr/bin/ssh -o IdentitiesOnly=yes -i ~/.ssh/IdentityFile2 -a eintragen
    Damit werden Submodule auch ohne insteadOf einfacher

    • Offen bleibt, was man macht, wenn es mehr als eine SSH-Identität gibt
  • Ich nutze schon lange verzeichnisbasiertes includeIf (https://www.bobek.cz/til/git-identities/), aber hasconfig:remote ist wirklich sauber
    Es funktioniert sogar beim Klonen eines Repositories

  • includeIf ist ziemlich gut
    Aktuell halte ich die SSH-Komplexität in ~/.ssh und habe je Kunde/Projekt/Identität jeweils ein Include
    Für Dinge wie GitHub, bei denen es keinen eindeutigen Hostnamen gibt, verwende ich einen Host-Alias wie customer-github und konfiguriere ihn mit HostName github.com, IdentityFile ~/.ssh/customer_rsa, User git
    Danach muss man bei git clone nur noch diesen Alias verwenden

  • Ich hatte dasselbe Problem, und jetzt gibt es also eine Lösung
    Mit NixOS und home-manager unter Linux und Mac wird diese Konfiguration einfach
    In programs.git.includes trägt man condition = "hasconfig:remote.*.url:git@github.com:/**" und die Einstellung für user.email ein
    Siehe: https://nix-community.github.io/home-manager/options.xhtml#opt-programs.git.includes

    • Das wirkt weniger einfach, als es direkt in .gitconfig zu schreiben
      Es sind dieselbe Bedingung und dieselbe Einstellung wie im Artikel, nur kommen hier noch ein Build-/Template-Schritt und das Lernen einer neuen Programmiersprache mit ungewöhnlicher Syntax dazu
  • Ich hatte Arbeit und private Konfiguration bereits mit includeIf: "gitdir" getrennt, aber hasconfig:remote ist ein echter Gamechanger

    • Unglaublich, dass dieser Schatz drei Jahre lang als Entwurf versteckt war
  • Consultants empfehle ich immer nachdrücklich, für die Arbeit eine separate Maschine zu verwenden oder mindestens einen separaten OS-Benutzer
    Wer eine private Maschine für die Arbeit nutzt, läuft Gefahr, in große Schwierigkeiten zu geraten

    • „Eine private Maschine für die Arbeit nutzen“ ist ein sehr weiter Begriff
      Es gibt Fälle, in denen man bei einem remote-first Unternehmen den Laptop selbst stellt und alle 2–3 Jahre Geld für ein neues Gerät bekommt, es aber trotzdem der private Laptop bleibt; oder man ist nur befristeter Contractor
      Man sollte genauer erklären, in welchen Situationen warum ein Problem entsteht
      Die Risiken sind real, aber wenn man sie nicht aufzählen kann, ist es weniger Aufklärung als das Verbreiten von FUD
  • Ein Tool, das ich gebaut habe, um die Git-Identität pro Projekt einfach zu wechseln: https://github.com/cquintana92/git-switch-user
    Nachdem man die Identitäten eingerichtet hat, führt man $ git su Personal oder $ git su Work aus, und E-Mail, Name, SSH-Key sowie optional ein PGP-Key werden in der .git/config des Repositories gesetzt
    Das hat mir viel Zeit gespart