Aller au contenu
Développement medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Nettoyer l'historique et les fichiers Git

9 min de lecture

Le fichier est dans .gitignore mais Git le suit toujours ? Vous avez commité un secret ? Votre repo fait des centaines de Mo à cause d’un binaire ? Ce guide couvre les trois problèmes de nettoyage les plus fréquents : arrêter de suivre un fichier, purger des données sensibles de tout l’historique, et réduire la taille d’un dépôt.

Prérequis : Enregistrer des modifications et Réécrire l’historique.

  • Arrêter de suivre un fichier sans le supprimer du disque
  • Supprimer un fichier sensible de tout l’historique avec git filter-repo
  • Appliquer le bon workflow selon que le secret est local ou déjà poussé
  • Déboguer .gitignore quand un fichier continue d’être tracké malgré la règle
SymptômeCauseSection
Fichier dans .gitignore mais suivi par GitAjouté avant le .gitignore« Arrêter de suivre un fichier »
.gitignore ne semble pas fonctionnerErreur de syntaxe ou de priorité« Débugger un .gitignore »
Secret/mot de passe commité par erreurVisibles dans l’historique« Supprimer un secret de l’historique »
Dépôt volumineux (> 100 Mo)Fichier binaire dans l’historique« Réduire la taille du dépôt »

Vous avez ajouté config/local.json au repo avant de mettre la règle dans .gitignore. Le fichier est ignoré pour les futures modifications, mais Git le suit toujours car il est dans l’index.

Fenêtre de terminal
git rm --cached config/local.json

--cached retire le fichier de l’index (Git arrête de le suivre) sans le supprimer du disque. Le fichier reste dans votre répertoire de travail.

Commitez le changement :

Fenêtre de terminal
git commit -m "chore: arrêter de suivre config/local.json"

Vérification :

Fenêtre de terminal
git status
# config/local.json ne doit plus apparaître

Pour un dossier entier :

Fenêtre de terminal
git rm -r --cached node_modules/
git commit -m "chore: arrêter de suivre node_modules"

Le .gitignore ne fonctionne pas comme attendu ? Utilisez git check-ignore pour comprendre pourquoi :

Fenêtre de terminal
git check-ignore -v config/local.json

Sortie si le fichier est ignoré :

.gitignore:3:config/*.json config/local.json

Cela indique quelle règle (fichier, ligne) cause l’ignorance. Si aucune sortie, le fichier n’est pas ignoré.

Quand plusieurs règles s’appliquent, la dernière règle gagne :

# Ignorer tous les logs
*.log
# MAIS garder error.log
!error.log
RègleSignification
*.logIgnore tous les fichiers .log
!error.logNégation — force le suivi de error.log
logs/Ignore le dossier logs et tout son contenu
logs/*.logIgnore les .log dans logs/ (pas les sous-dossiers)
logs/**/*.logIgnore les .log dans logs/ et tous ses sous-dossiers
# ❌ Ne fonctionne pas : le fichier est déjà suivi
secret.env
# ✅ Solution : d'abord git rm --cached, puis ajouter la règle
# ❌ La négation ne fonctionne pas si le dossier parent est ignoré
build/
!build/important.js
# ✅ Solution : ignorer le contenu, pas le dossier
build/*
!build/important.js
Fenêtre de terminal
git status --ignored

Un mot de passe, une clé API ou un token a été commité. Même si vous le supprimez dans un nouveau commit, il reste visible dans l’historique. Voici le workflow complet.

  1. Installez git-filter-repo

    git-filter-repo remplace l’ancien filter-branch (plus sûr, plus rapide). Installez-le :

    Fenêtre de terminal
    pip install git-filter-repo

    Vérification :

    Fenêtre de terminal
    git filter-repo --version
  2. Sauvegardez votre repo (par sécurité)

    Fenêtre de terminal
    cp -r mon-projet mon-projet-backup
  3. Supprimez le fichier de tout l’historique

    Fenêtre de terminal
    git filter-repo --path .env --invert-paths

    --invert-paths signifie : « supprime tout ce qui correspond au path donné ». Le fichier .env disparaît de tous les commits.

  4. Vérifiez que le fichier n’apparaît plus

    Fenêtre de terminal
    git log --all --full-history -- .env
    # Aucun résultat = le fichier est purgé
  5. Ajoutez le fichier au .gitignore

    Fenêtre de terminal
    echo ".env" >> .gitignore
    git add .gitignore
    git commit -m "chore: ajouter .env au gitignore"
  6. Force push vers le remote

    Fenêtre de terminal
    git push --force --all
    git push --force --tags
  7. Prévenez votre équipe

    Tous les collègues doivent re-cloner ou exécuter :

    Fenêtre de terminal
    git fetch --all
    git reset --hard origin/main

Supprimer un texte spécifique (pas un fichier entier)

Section intitulée « Supprimer un texte spécifique (pas un fichier entier) »

Si le secret est une ligne à l’intérieur d’un fichier (pas le fichier entier) :

Fenêtre de terminal
git filter-repo --replace-text <(echo 'MON_SECRET_123==>***REDACTED***')

Cela remplace toutes les occurrences de MON_SECRET_123 par ***REDACTED*** dans tous les fichiers de tout l’historique.

Un fichier binaire volumineux (dump SQL, vidéo, archive) a été commité et gonfle le repo :

Fenêtre de terminal
git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| awk '/^blob/ {print $3, $4}' \
| sort -rn \
| head -20

Sortie :

52428800 data/dump.sql
10485760 assets/video-demo.mp4
Fenêtre de terminal
git filter-repo --path data/dump.sql --invert-paths

Pour éviter que cela ne se reproduise, utilisez Git LFS (Large File Storage) pour les fichiers volumineux :

Fenêtre de terminal
git lfs install
git lfs track "*.sql"
git lfs track "*.mp4"
git add .gitattributes
git commit -m "chore: configurer Git LFS pour SQL et vidéos"
SymptômeCause probableSolution
.gitignore ne fonctionne pasFichier déjà suivi (dans l’index)git rm --cached fichier d’abord
filter-repo refuse de s’exécuterRepo pas « fresh clone »Ajoutez --force ou reclonez
Le repo est toujours gros après filter-repoObjets non collectésgit reflog expire --expire=now --all && git gc --prune=now --aggressive
Les collègues ont des erreurs après le force pushHistoriques divergentsIls doivent re-cloner ou git fetch --all && git reset --hard origin/main
La négation !fichier dans .gitignore ne marche pasLe dossier parent est ignoré avec /Ignorer le contenu dossier/* au lieu du dossier dossier/
  • git rm --cached arrête de suivre un fichier sans le supprimer du disque
  • .gitignore ne s’applique qu’aux fichiers non encore suivis — d’abord rm --cached, puis .gitignore
  • git check-ignore -v est l’outil de debug du .gitignore
  • Secret commité = secret compromis — changez-le immédiatement, avant le nettoyage Git
  • git filter-repo supprime un fichier de tout l’historique (remplace filter-branch)
  • Après un filter-repo, il faut force push et prévenir l’équipe
  • Git LFS prévient le problème des gros fichiers en les stockant séparément

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn