3 points par GN⁺ 2024-11-26 | 1 commentaires | Partager sur WhatsApp
  • Dans un environnement où les dépôts personnels et professionnels sont tous placés dans ~/workspace, il est plus précis de séparer les identités Git en se basant sur l’URL du remote plutôt que sur l’emplacement du dossier
  • Le includeIf de Git peut charger des configurations par chemin via gitdir, mais si des dépôts de plusieurs comptes sont mélangés dans un même répertoire de travail, la séparation par chemin atteint vite ses limites
  • En utilisant la condition hasconfig:remote.*.url:, on peut inclure des fichiers de configuration distincts selon des motifs d’URL de remote, comme GitHub, GitLab, SourceHut ou une organisation GitHub spécifique
  • Les clés SSH doivent être gérées séparément dans ~/.ssh/config avec Host, Hostname, User et IdentityFile, et pour utiliser des clés différentes selon l’organisation sur un même github.com, il faut des alias de Host
  • En configurant aussi url.<base>.insteadOf, on peut continuer à utiliser git@github.com:orgname/project au quotidien, tout en le remplaçant en interne par gh-work:orgname afin d’appliquer la bonne configuration SSH

Séparer la configuration Git selon l’URL du remote

  • Les exemples classiques de includeIf incluent différents fichiers de configuration selon le chemin du répertoire local, comme gitdir:~/code/** ou gitdir:~/work/**
    • Sous ~/code, on peut charger ~/.config/git/personal, et sous ~/work, ~/.config/git/work
    • Les fichiers inclus contiennent généralement l’identité Git et la clé de signature, comme user.name, user.email et user.signingkey
  • Si tout le code est placé sous ~/workspace, des dépôts personnels, work-1 et work-2 peuvent se retrouver mélangés dans la même arborescence, ce qui rend la séparation souhaitée difficile à obtenir avec les seules conditions basées sur le chemin
  • Avec hasconfig:remote.*.url: de Git, on peut inclure un fichier de configuration uniquement si le dépôt courant possède une URL de remote donnée
    • si cela correspond à git@github.com:*/**, charger ~/.config/git/config-gh
    • si cela correspond à git@github.com:orgname/**, charger ~/.config/git/config-gh-org
    • si cela correspond à git@gitlab.com:*/**, charger ~/.config/git/config-gl
    • si cela correspond à git@git.sr.ht:*/**, charger ~/.config/git/config-srht
  • Git inclut la dernière configuration qui correspond, donc l’ordre des conditions est important
    • la condition github.com:orgname/** doit être placée sous la condition générale github.com:*/** afin que la configuration dédiée à l’organisation ne soit pas écrasée par la configuration GitHub générique
  • En pratique, un dépôt avec un remote github.com:orgname/** utilisera config-gh-org, tandis que les autres dépôts GitHub utiliseront la configuration GitHub générale

Faire correspondre les informations de connexion par organisation avec les clés SSH et insteadOf

1 commentaires

 
GN⁺ 2024-11-26
Commentaires sur Hacker News
  • Au lieu de insteadOf, cloner le dépôt en gh-work:org/repo et mettre dans la configuration Git includeIf "hasconfig:remote.*.url:gh-work:**/**"
    Ainsi, les dépôts clonés avec l’identité SSH définie sous gh-work récupèrent automatiquement la configuration gh-work.inc, qui contient l’identité Git ainsi que la clé de signature et la configuration SSH
    Au final, le nom gh-work sert de critère pour distinguer l’identité SSH de l’identité Git, ce qui est plus facile à comprendre

    • La solution de l’article me mettait mal à l’aise parce qu’elle semblait offrir plus de degrés de liberté que nécessaire, mais cela paraît être une façon élégante de réduire les paramètres d’exécution à un seul
    • includeIf est sensible à la casse, et, pour les priorités, la dernière configuration l’emporte
      Pour vérifier que cela fonctionne correctement, il suffit d’exécuter git remote get-url origin et git config --get user.email
    • Cette approche pouvait casser des scripts qui s’attendent à ce que l’URL du dépôt distant ait une certaine forme
  • À mon avis, une meilleure méthode consiste à définir dans le .gitconfig de HOME des alias par identité, puis à exécuter git config-company ou git config-personal juste après l’initialisation ou le clonage du dépôt
    Il suffit d’activer user.useConfigOnly = true et, dans les alias, de configurer user.email, user.name et core.sshCommand du dépôt local avec la clé SSH personnelle ou professionnelle correspondante

    • Le problème reste de savoir comment effectuer le clonage initial sans la bonne configuration SSH dès le départ
      L’avantage de la méthode de l’article semble être que, si l’on clone depuis l’organisation, cela fonctionne tout simplement
  • Dans une startup où j’ai travaillé autrefois, quelqu’un changeait chaque jour son identité pour un nom fantaisiste tiré d’un conte
    Les commits du lundi étaient signés Mr. Bunnymann, ceux du mardi Doctor Funtime, etc., ce qui rendait les analyses forensiques de versioning très pénibles
    En étant charitable, il cherchait peut-être à rappeler que n’importe qui peut mettre n’importe quelle valeur dans sa configuration d’identité, et qu’il ne faut donc pas trop s’y fier

    • Dans une culture sans blâme, en analyse forensique du contrôle de version, le plus important aurait été moins de savoir qui l’a fait que quand cela s’est produit et autour de quels changements
      Cela dit, savoir qui l’a fait aide tout de même si l’on veut poser des questions sur les détails ou anticiper le style et l’expertise de la personne
      En exigeant des signatures GPG sur les commits et en enregistrant les identités GPG autorisées, on peut identifier l’auteur réel par la signature plutôt que par les métadonnées auteur/committer
      Bien sûr, « simplement » et les signatures GPG ne vont pas toujours très bien ensemble
    • Il faut leur accorder le même niveau de confiance qu’aux documents ou signatures produits par les employés
      Si l’on ne peut pas faire confiance à un employé pour identifier correctement ses propres commits, à mon avis il faut le licencier
    • En étant charitable, je me demande s’il utilisait la même clé de signature
    • C’est étonnant qu’il ait été payé pour ce genre de blague
    • Git prend en charge nativement la séparation entre auteur et committer, et il a probablement seulement changé l’attribut auteur
  • Sans avoir à toucher à ~/.ssh/config, on peut mettre core.sshCommand = /usr/bin/ssh -o IdentitiesOnly=yes -i ~/.ssh/IdentityFile2 -a dans ~/.gitconfig ou, comme dans l’article, dans ~/.config/git/personal
    Cela simplifie les sous-modules même sans insteadOf

    • Reste la question de savoir quoi faire lorsqu’on a plusieurs identités SSH
  • J’utilisais depuis longtemps includeIf basé sur les répertoires (https://www.bobek.cz/til/git-identities/), mais hasconfig:remote est vraiment propre
    Cela fonctionne aussi lors du clonage d’un dépôt

  • includeIf est plutôt très bien
    Pour l’instant, je laisse la complexité SSH dans ~/.ssh et j’ai un include par client/projet/identité
    Pour ceux qui n’ont pas de nom d’hôte unique, comme GitHub, j’ajoute un alias d’hôte du type customer-github, avec une configuration comme HostName github.com, IdentityFile ~/.ssh/customer_rsa, User git
    Ensuite, il suffit d’utiliser cet alias dans git clone

  • J’avais le même problème, et voilà maintenant une solution
    Avec NixOS et home-manager sur Linux et Mac, cette configuration devient simple
    Il suffit de mettre dans programs.git.includes condition = "hasconfig:remote.*.url:git@github.com:/**" et la configuration user.email
    Référence : https://nix-community.github.io/home-manager/options.xhtml#opt-programs.git.includes

    • Cela semble moins simple que de l’écrire directement dans .gitconfig
      C’est la même condition et la même configuration que dans l’article, mais on y ajoute une étape de build/templating et l’apprentissage d’un nouveau langage de programmation à la syntaxe particulière
  • Je séparais déjà mes configurations pro et perso avec includeIf: "gitdir", mais hasconfig:remote change complètement la donne

    • J’ai du mal à croire que ce trésor soit resté caché pendant trois ans à l’état de brouillon
  • Aux consultants, je recommande toujours fortement d’utiliser une machine séparée pour le travail, ou au minimum un utilisateur d’OS séparé
    Utiliser une machine personnelle pour le travail expose à de sérieux ennuis

    • « Utiliser une machine personnelle pour le travail » couvre un champ très large
      Dans une entreprise remote-first, on peut devoir fournir soi-même son ordinateur portable et recevoir tous les 2 ou 3 ans un budget pour en acheter un nouveau, tout en restant sur son portable personnel ; on peut aussi être contractuel temporaire
      Il faut préciser plus concrètement dans quelles situations cela pose problème et pourquoi
      Les risques sont réels, mais si on ne les énumère pas, cela ressemble davantage à de la FUD qu’à de la pédagogie
  • Voici un outil que j’ai créé pour changer facilement d’identité Git selon le projet : https://github.com/cquintana92/git-switch-user
    Après avoir défini les identités, exécuter $ git su Personal ou $ git su Work configure l’e-mail, le nom, la clé SSH et, éventuellement, la clé PGP dans le .git/config du dépôt
    Cela m’a fait gagner beaucoup de temps

    • Il existe aussi un outil de gestion des identités GitHub pour l’accès Git via SSH : https://github.com/dolmen/github-keygen
      C’est un outil vieux de 12 ans, mais il est encore activement maintenu