Introduction
Tout ce que Git sait d'un dépôt vit dans .git/. Savoir ce qu'est chaque entrée dissipe le mystère des diagnostics « que vient-il de se passer ? ».
Disposition de haut niveau
.git/
HEAD # ref symbolique vers la branche courante
config # configuration locale du dépôt
description # utilisé par gitweb
index # la zone de staging
packed-refs # refs de branches et tags packées (optionnel)
hooks/ # scripts de hooks côté client
info/ # fichier excludes et autres infos locales du dépôt
logs/ # reflogs
objects/ # tous les objets (loose + pack/)
refs/ # branches, tags, tracking distant
worktrees/ # worktrees liés (s'il y en a)
modules/ # répertoires .git des sous-modules
HEAD et refs
cat .git/HEAD
ls .git/refs/heads
ls .git/refs/remotes/origin
ls .git/refs/tags
cat .git/packed-refs | head
objects/
Objets loose sous objects/xx/, objets packés dans objects/pack/. Ne pas toucher à la main.
logs/
Le reflog. logs/HEAD enregistre chaque mouvement de HEAD ; logs/refs/heads/<branch> enregistre l'historique de chaque branche.
cat .git/logs/HEAD | head
hooks/
Exemples de scripts de hook, tous nommés *.sample par défaut. Pour activer, retirez le suffixe et rendez exécutable :
cd .git/hooks
cp pre-commit.sample pre-commit
chmod +x pre-commit
info/
info/exclude est un fichier d'ignore par dépôt et par clone (non commité). info/refs est généré par git update-server-info pour les serveurs HTTP dumb.
config
Configuration locale au format INI. Éditez via git config --local ou git config -e :
cat .git/config
git config --local user.email "[email protected]"
worktrees/
Chaque worktree lié a un répertoire sous .git/worktrees/<name>/ avec son propre HEAD, index et logs.
modules/
Pour les dépôts avec sous-modules, le répertoire .git de chaque sous-module vit ici, et l'arborescence de travail du sous-module contient un petit fichier .git pointant vers lui.
Dépôts nus
Un dépôt nu a le même contenu mais au niveau supérieur (pas de wrapper .git/) et sans arborescence de travail. Convention : nommez le répertoire project.git.
git rev-parse pour les chemins
Les scripts qui ont besoin de trouver des chemins dans .git/ ne devraient jamais supposer que le répertoire est littéralement nommé .git. Les sous-modules utilisent un fichier .git pointant ailleurs ; les worktrees ont des gitdirs liés ; les dépôts nus n'ont pas de gitdir séparé. Utilisez git rev-parse :
git rev-parse --git-dir # gitdir réel pour le dépôt courant
git rev-parse --git-common-dir # dir partagé pour les worktrees
git rev-parse --show-toplevel # racine de l'arborescence de travail
git rev-parse --is-inside-git-dir
git rev-parse --is-inside-work-tree
Ces cinq questions couvrent presque toutes les vérifications « où suis-je ? » dont un script a besoin.
Erreurs fréquentes
Éditer les fichiers à l'intérieur de .git/ directement. Presque tout a une commande Git qui le fait correctement, atomiquement et avec hooks. Sauvegarder seulement l'arborescence de travail et oublier que .git/ contient tout l'historique ; sauvegardez tout le répertoire. Partager .git/hooks/ en supposant qu'ils se propagent ; les hooks ne sont pas versionnés. Utilisez core.hooksPath ou un outil comme pre-commit pour les partager. Enfin, supprimer .git/index sur impulsion ; reconstruisez avec git read-tree HEAD, mais seulement après sauvegarde.