Introduction
L'index est un fichier binaire à .git/index qui reflète un objet tree : une liste triée de chemins avec mode, hachage et infos stat. C'est la zone de staging pour le prochain commit et un cache qui permet à Git de sauter le re-hachage des fichiers inchangés.
L'inspecter
git ls-files --stage
# 100644 a1b2c3... 0 README.md
# 100644 e4f5g6... 0 src/main.c
Stage 0 signifie « pas de conflit ». Pendant un merge, les chemins en conflit obtiennent les stages 1 (base), 2 (ours), 3 (theirs).
Ce que le stat caching apporte
L'index stocke aussi ctime, mtime, size et inode pour chaque chemin. git status les compare à l'arborescence de travail avant de hacher ; s'ils correspondent, le fichier est supposé inchangé. C'est pourquoi git status est rapide sur d'énormes arbres.
git update-index --refresh
git update-index --really-refresh
Modifier l'index
git add file.txt # stager depuis l'arborescence de travail
git rm --cached file.txt # retirer de l'index, garder sur disque
git restore --staged file.txt # désindexer
git update-index --chmod=+x bin/run # changer le bit exécutable
Assume unchanged et skip-worktree
Deux flags disent à Git d'ignorer certains chemins :
git update-index --assume-unchanged config.local
git update-index --skip-worktree config.local
assume-unchanged: un indice de performance ; Git peut quand même remarquer les changements.skip-worktree: plus fort ; destiné aux fichiers que l'utilisateur garde modifiés localement.
Aucun ne remplace .gitignore ; les deux sont des bidouillages locaux à l'espace de travail, non partageables.
Lire et écrire des trees
git write-tree # capturer l'index comme objet tree
git read-tree HEAD # reset l'index à un tree
git read-tree --reset -u HEAD # met aussi à jour l'arborescence de travail
Ces commandes de plomberie sous-tendent commit, checkout et merge.
Conflits dans l'index
Pendant un merge, l'index devient la source de vérité pour ce qui est non résolu :
git ls-files -u
# 100644 a1... 1 src/main.c
# 100644 b2... 2 src/main.c
# 100644 c3... 3 src/main.c
Résoudre un conflit signifie écrire le contenu final et le git add, ce qui fait revenir à une seule entrée stage 0.
Sparse checkout et l'index sparse
Sparse checkout peuple l'arborescence de travail avec seulement un sous-ensemble du tree du dépôt, utile dans les monorepos. Avec le mode cone plus l'index sparse, l'index lui-même se réduit au cône actif, rendant les opérations sur les énormes dépôts rapides :
git sparse-checkout init --cone
git sparse-checkout set src/myteam docs
git sparse-checkout list
git sparse-checkout disable
L'index sparse marque les entrées omises avec un bit spécial pour que Git puisse les développer paresseusement seulement quand les commandes en ont besoin. Cette fonctionnalité nécessite Git 2.32 ou plus récent pour une fonctionnalité complète.
Erreurs fréquentes
Croire que l'index n'est que « ce qui est stagé ». C'est aussi un cache et un traqueur de conflits. Supprimer .git/index en cas de blocage ; reconstruisez avec git read-tree HEAD, mais vous perdez tout staging non commité. Utiliser --assume-unchanged comme substitut à .gitignore ; le prochain clone ne l'honorera pas. Enfin, attendre que l'index suive les répertoires vides ; il ne peut pas. Utilisez un fichier marqueur (.gitkeep) si vous devez commiter un dossier vide.