Résolution des problèmes de configuration Git : correctifs courants et bonnes pratiques

Corrigez les problèmes de configuration Git en traçant l'origine des paramètres, en résolvant les problèmes d'identité, d'alias, de hooks, de fins de ligne, de pull et d'identifiants.

Résolution des problèmes de configuration Git : correctifs courants et bonnes pratiques

La plupart des problèmes de configuration Git semblent plus étranges qu'ils ne le sont. Git fait généralement exactement ce que l'un de ses fichiers de configuration lui a demandé de faire. La partie difficile est de trouver quel fichier, car le paramètre peut se trouver dans le dépôt, votre configuration utilisateur, une configuration système, un fichier inclus ou une inclusion conditionnelle qui ne s'applique que sous un répertoire.

La commande à laquelle je recours en premier est celle-ci :

git config --list --show-origin --show-scope

Si votre version de Git ne supporte pas --show-scope, utilisez :

git config --list --show-origin

L'origine vous indique quel fichier a fourni chaque valeur. Cela importe plus que la valeur seule. Voir [email protected] ne suffit pas ; vous devez savoir si cela provient de .git/config, ~/.gitconfig, /etc/gitconfig ou d'un profil de travail inclus.

La configuration Git a un ordre de priorité. La configuration locale du dépôt l'emporte normalement sur la configuration utilisateur globale, et la configuration globale l'emporte sur la configuration système. Les options de ligne de commande et les variables d'environnement peuvent toutes les remplacer pour une commande. Les inclusions conditionnelles ajoutent une autre couche : un fichier global peut dire : "Quand je suis dans ce répertoire, charge aussi cette autre configuration."

Vous pouvez inspecter un paramètre avec sa source :

git config --show-origin --get user.email
git config --show-origin --get core.autocrlf
git config --show-origin --get-regexp '^alias\.'

Cette habitude évite beaucoup d'éditions inutiles. Si un dépôt a user.email défini localement, changer git config --global user.email n'affectera pas les commits dans ce dépôt.

Nom ou email incorrect sur les commits

Le symptôme est simple : les commits montrent le mauvais auteur. Cela arrive souvent lorsque vous utilisez le même ordinateur portable pour des projets professionnels et personnels, ou lorsque vous clonez un dépôt d'entreprise avant de définir votre email professionnel.

Vérifiez ce que Git utilisera dans le dépôt actuel :

git config user.name
git config user.email
git config --show-origin --get user.email

Définissez votre identité par défaut globalement :

git config --global user.name "Votre Nom"
git config --global user.email "[email protected]"

Pour un dépôt, définissez-la localement :

git config --local user.name "Votre Nom"
git config --local user.email "[email protected]"

Si vous voulez que Git refuse les commits lorsque l'identité n'est pas configurée explicitement, utilisez :

git config --global user.useConfigOnly true

Ce paramètre est utile pour les personnes qui changent d'identité. Il peut ennuyer les débutants car Git cessera de deviner à partir du nom d'utilisateur système et du nom d'hôte. Utilisez-le lorsque vous préférez échouer un commit plutôt que d'en créer un sous la mauvaise adresse.

Pour une séparation travail/personnel plus propre, utilisez des inclusions conditionnelles :

# ~/.gitconfig
[user]
    name = Votre Nom
    email = [email protected]

[includeIf "gitdir:~/travail/"]
    path = ~/.gitconfig-travail

Puis mettez ceci dans ~/.gitconfig-travail :

[user]
    email = [email protected]

La barre oblique finale dans gitdir:~/travail/ est importante car elle signifie les dépôts sous ce répertoire. Si cela ne se déclenche pas, exécutez git config --list --show-origin depuis un dépôt de travail et vérifiez si le fichier inclus apparaît.

Si vous avez déjà fait des commits avec le mauvais email, changer la configuration ne corrige que les futurs commits. Pour les commits non publiés, vous pouvez amender ou rebaser. Pour les commits déjà poussés vers une branche partagée, demandez avant de réécrire l'historique.

Alias qui ne fonctionnent pas

Les alias Git sont stockés sous alias.*. Listez-les comme ceci :

git config --get-regexp '^alias\.'

Un alias normal se développe en une sous-commande Git :

git config --global alias.st 'status -sb'
git st

Si l'alias a besoin d'un pipeline shell, d'une expansion de variable, de cd ou d'une autre commande non Git, il doit commencer par ! :

git config --global alias.recent '!git for-each-ref --sort=-committerdate --count=10 --format="%(refname:short)" refs/heads/'

Sans !, Git essaie de traiter le premier mot comme une commande Git. ls -la devient "exécute la commande Git nommée ls", ce qui n'est pas ce que vous vouliez.

Les guillemets sont l'autre échec courant. Si vous définissez des alias depuis le shell, utilisez des guillemets simples autour de l'alias entier lorsque c'est possible, puis des guillemets doubles à l'intérieur si nécessaire. Différents shells gèrent les guillemets différemment, en particulier PowerShell et cmd.exe. Si un alias complexe continue de se casser, éditez le fichier de configuration directement :

git config --global --edit

Une astuce de débogage pratique consiste à commencer par la commande en dehors de Git. Une fois qu'elle fonctionne, collez-la dans l'alias. S'il s'agit d'un alias shell, préfixez-le avec ! et testez à nouveau.

Faites également attention aux alias qui masquent les modèles mentaux. Un alias nommé pull ou merge peut rendre le comportement de Git surprenant. Git ne permet pas aux alias de remplacer directement les commandes intégrées, mais les alias shell et les scripts wrapper peuvent le faire. Si git pull se comporte étrangement, vérifiez aussi votre configuration shell :

type git
alias | grep git

Hooks qui ne s'exécutent jamais

Les hooks échouent pour trois raisons ennuyeuses : Git cherche dans un répertoire de hooks différent, le fichier n'est pas exécutable, ou le script suppose un environnement qu'il n'a pas.

Vérifiez le chemin des hooks configuré :

git config --show-origin --get core.hooksPath

Si cela affiche .githooks, Git utilisera .githooks/pre-commit, pas .git/hooks/pre-commit. Si cela n'affiche rien, Git utilise .git/hooks.

Sur macOS et Linux, vérifiez les permissions :

ls -l .git/hooks/pre-commit .githooks/pre-commit 2>/dev/null
chmod +x .githooks/pre-commit

Un hook qui se termine avec un statut non nul bloque l'opération Git. Ajoutez un traçage temporaire près du début :

#!/usr/bin/env bash
set -x
pwd
env | sort

Ne laissez pas un traçage bruyant dans un hook partagé. Il devient rapidement illisible.

Les problèmes de chemin sont courants avec les clients GUI. Un hook qui fonctionne dans votre terminal peut échouer dans un IDE car l'IDE n'a pas chargé votre profil shell. Préférez les commandes locales au projet lorsque c'est possible :

./node_modules/.bin/eslint .

ou vérifiez la commande et affichez un message utile :

if ! command -v npm >/dev/null 2>&1; then
  echo "npm est requis pour ce hook mais n'a pas été trouvé dans PATH."
  exit 1
fi

Les fins de ligne continuent de changer

Les problèmes de fin de ligne se manifestent par des fichiers qui apparaissent modifiés immédiatement après le checkout, des diffs volumineux où chaque ligne a changé, ou des scripts qui échouent sur Linux après avoir été édités sur Windows.

Vérifiez votre paramètre :

git config --show-origin --get core.autocrlf
git config --show-origin --get core.eol

Les choix courants sont :

# Checkout adapté à Windows, LF dans le dépôt
git config --global core.autocrlf true

# Adapté à macOS/Linux : convertir CRLF en LF uniquement lors du commit
git config --global core.autocrlf input

# Aucune conversion automatique
git config --global core.autocrlf false

Pour une équipe, .gitattributes est plus fiable que de dire à chaque développeur de définir correctement les paramètres globaux. Mettez les règles du projet dans le dépôt :

* text=auto
*.sh text eol=lf
*.bat text eol=crlf
*.png binary
*.jpg binary
*.pdf binary

Après avoir ajouté ou modifié .gitattributes, normalisez les fichiers délibérément :

git add --renormalize .
git status

Examinez attentivement ce diff. Il peut toucher de nombreux fichiers, et vous ne voulez pas mélanger la normalisation des fins de ligne avec du travail sur des fonctionnalités.

Pull, Push ou Merge utilise la mauvaise valeur par défaut

Parfois, le problème de configuration n'est pas l'identité ou les fins de ligne. C'est Git qui choisit une stratégie de pull à laquelle vous ne vous attendiez pas.

Vérifiez les paramètres liés au pull :

git config --show-origin --get pull.rebase
git config --show-origin --get pull.ff
git config --show-origin --get branch.main.rebase

Si git pull continue de rebaser alors que vous attendiez un merge, pull.rebase ou un paramètre spécifique à une branche peut être activé. S'il refuse les pulls non fast-forward, pull.ff=only peut être défini. Ces paramètres ne sont pas mauvais en eux-mêmes ; ils doivent simplement correspondre au flux de travail de l'équipe.

Définissez une valeur par défaut explicite au lieu de vivre avec des avertissements et des surprises :

# Merge sur pull
git config --global pull.rebase false

# Rebase sur pull
git config --global pull.rebase true

# Autoriser uniquement les pulls fast-forward
git config --global pull.ff only

Pour une branche :

git config branch.main.rebase true

Confusion du gestionnaire d'identifiants

Les problèmes d'authentification ressemblent souvent à des problèmes distants mais proviennent de la configuration locale. Git peut utiliser un gestionnaire d'identifiants qui a un ancien token en cache.

Vérifiez les gestionnaires :

git config --show-origin --get-all credential.helper

Vous pouvez voir osxkeychain, manager, manager-core, store ou cache. Plusieurs gestionnaires peuvent exister. Si Git continue d'envoyer le mauvais identifiant, supprimez-le du trousseau système ou du gestionnaire d'identifiants plutôt que de modifier des URLs distantes aléatoires.

Vérifiez également le remote :

git remote -v

SSH et HTTPS utilisent des chemins d'authentification différents. Si un dépôt utilise [email protected]:org/repo.git et un autre utilise https://github.com/org/repo.git, ils n'utiliseront pas nécessairement les mêmes identifiants.

Une routine de débogage fiable

Lorsque la configuration Git semble incohérente, utilisez une routine au lieu de deviner :

  1. Exécutez la commande qui échoue depuis la racine du dépôt.
  2. Inspectez le paramètre exact avec git config --show-origin --get <nom>.
  3. Listez les paramètres connexes avec git config --list --show-origin --show-scope.
  4. Vérifiez la configuration locale dans .git/config avant de modifier la configuration globale.
  5. Vérifiez les inclusions conditionnelles si le problème ne se produit que sous un répertoire.
  6. Faites la plus petite modification de configuration et réexécutez la commande d'origine.

La configuration Git est puissante car elle peut être superposée. C'est aussi pourquoi elle devient confuse. La solution est de rendre les couches visibles, puis de modifier la couche qui gagne réellement.

Quand la configuration est différente dans un IDE

Une classe déroutante de problèmes Git n'apparaît que dans un éditeur ou une interface graphique. Le terminal utilise une identité, mais l'IDE commit avec une autre. Un hook passe dans votre shell, mais échoue depuis le panneau de commit. Une invite d'identifiant apparaît dans le terminal, tandis que l'interface graphique réessaie silencieusement avec un ancien token.

La raison est généralement l'environnement. Votre shell interactif peut charger .bashrc, .zshrc, des gestionnaires SDK, des gestionnaires de version de langage et des entrées PATH personnalisées. Une interface graphique lancée depuis le bureau peut ne rien charger de tout cela. Git lui-même lit les mêmes fichiers de configuration, mais les hooks et les gestionnaires d'identifiants peuvent voir un monde différent.

Pour déboguer, créez un hook temporaire qui imprime l'environnement dans un fichier local :

#!/usr/bin/env bash
{
  date
  pwd
  git --version
  git config --list --show-origin
  env | sort
} > /tmp/git-hook-debug.log
exit 1

Exécutez l'action Git depuis l'IDE, puis inspectez /tmp/git-hook-debug.log. Supprimez le hook ensuite. Cela vous indique ce que Git et le hook ont réellement vu, au lieu de ce que votre terminal voit.

Pour les problèmes d'identité dans les clients GUI, vérifiez si l'outil a ses propres paramètres Git. Certains clients utilisent le Git système ; d'autres intègrent Git ou stockent l'identité utilisateur dans les préférences de l'application. Si le client commit via Git, git log --format=fuller -1 montrera l'auteur et le committer résultants. Cela aide à séparer "la configuration Git était erronée" de "le GUI a utilisé son propre paramètre".

En cas de doute, rendez explicites les paramètres locaux du dépôt pour les projets importants :

git config --local user.email "[email protected]"
git config --local core.hooksPath .githooks

La configuration locale réduit les surprises car elle voyage avec les métadonnées du dépôt sur cette machine. Elle n'est toujours pas commitée, donc les règles partagées doivent résider dans des fichiers suivis tels que .gitattributes, .editorconfig, les scripts de hook et la documentation du projet.

Gardez une base de référence connue

Lorsque les problèmes de configuration reviennent, sauvegardez une petite base de référence connue pour vos propres machines. Elle n'a pas besoin d'être sophistiquée. Un ~/.gitconfig commenté avec votre identité, éditeur, comportement de branche par défaut, gestionnaire d'identifiants et inclusions suffit. Ensuite, lorsqu'un nouvel ordinateur portable se comporte différemment, vous pouvez comparer au lieu de redécouvrir chaque paramètre.

Les vérifications de base utiles incluent :

git config --global --list --show-origin
git config --global --get core.editor
git config --global --get init.defaultBranch
git config --global --get-all credential.helper

Soyez prudent lorsque vous copiez une configuration depuis Internet ou depuis un collègue. Les alias peuvent supposer des outils que vous n'avez pas. Les gestionnaires d'identifiants sont spécifiques à la plateforme. Les paramètres de fin de ligne peuvent être corrects pour leur OS et erronés pour le vôtre. Traitez la configuration Git comme la configuration shell : empruntez des idées, mais comprenez chaque ligne avant de la conserver.

Pour les mainteneurs de projet, la meilleure solution est de déplacer les attentes partagées hors de la configuration personnelle. Mettez les fins de ligne dans .gitattributes, le formatage dans la configuration du formateur, les fichiers ignorés dans .gitignore et les vérifications requises dans le CI. Moins un projet dépend de paramètres globaux invisibles, moins il crée de tickets de configuration.

Lorsque vous modifiez un paramètre pour résoudre un problème, notez s'il était local ou global. De nombreux mystères Git futurs commencent par une bonne solution temporaire locale que personne ne se rappelle six mois plus tard.