Réparer un dépôt Git corrompu : un guide de dépannage complet
Les dépôts Git sont généralement robustes, mais des facteurs externes tels qu'une défaillance matérielle, des plantages système soudains, des erreurs de disque, ou même une coupure de courant pendant une opération Git critique (comme le packaging d'objets ou la réécriture de l'historique) peuvent entraîner une corruption des données. Un dépôt corrompu peut se manifester par des erreurs confuses, une incapacité à committer, ou des rapports d'objets manquants.
Ce guide fournit une approche systématique, étape par étape, pour diagnostiquer le type de corruption, employer des techniques de réparation appropriées et récupérer les données perdues en toute sécurité. Étant donné que la corruption d'un dépôt peut entraîner une perte de données permanente, suivez toujours la bonne pratique consistant à créer une sauvegarde de sécurité avant de tenter des réparations invasives.
1. La sécurité d'abord : sauvegarder le dépôt corrompu
Avant d'initier toute commande de réparation, en particulier celles impliquant la manipulation du système de fichiers à l'intérieur du répertoire .git, vous devez créer une sauvegarde complète. Cela garantit que si le processus de réparation cause d'autres problèmes, vous pourrez revenir à l'état corrompu actuel.
# Naviguer en dehors du répertoire du dépôt
cd ..
# Créer une sauvegarde compressée du répertoire entier
tar -czvf myrepo_corrupted_backup.tar.gz myrepo/.git
# Alternativement, copier simplement le dossier .git
cp -r myrepo/.git myrepo_backup_$(date +%Y%m%d)
2. Diagnostiquer la corruption avec git fsck
L'outil principal pour vérifier l'intégrité d'un dépôt Git est git fsck (File System Check). Cette commande scanne la base de données d'objets et les références, à la recherche d'incohérences, d'objets manquants ou de liens brisés.
Exécutez la commande suivante pour une vérification complète :
# Exécuter la vérification d'intégrité avec une sortie détaillée
git fsck --full --unreachable --strict
Interprétation de la sortie de git fsck
| Message d'erreur | Signification | Gravité | Solution principale |
|---|---|---|---|
error: object XXXXX is missing |
Un objet blob, tree ou commit requis est complètement manquant. | Élevée | Récupération à partir de la source distante/sauvegarde. |
dangling commit XXXXX |
Un commit existe mais n'est référencé par aucune branche, tag ou reflog. | Faible/Moyenne | Récupération via git reflog. |
dangling blob XXXXX |
Des données existent mais ne sont liées à aucun commit ou tree. | Faible | Peut généralement être ignoré ou élagué. |
error: HEAD points to an unborn branch |
Le fichier .git/HEAD est corrompu ou pointe vers une branche qui n'existe pas. |
Moyenne | Correction manuelle de .git/HEAD ou git reset. |
3. Réparer l'index Git (.git/index)
Le fichier d'index est le cache de zone de staging que Git utilise pour suivre les changements entre votre répertoire de travail et le dernier commit. La corruption de l'index est l'un des problèmes les plus courants après un plantage du système ou un échec de fusion.
Si les opérations Git échouent avec des erreurs indiquant que l'index est invalide, incohérent ou illisible, l'index doit être reconstruit.
Méthode 1 : Forcer Git à relire l'index
Le moyen le plus sûr de tenter une réparation de l'index est d'effectuer un hard reset, ce qui force Git à réconcilier l'index et le répertoire de travail en se basant sur le dernier commit.
git reset --hard HEAD
Méthode 2 : Supprimer et recréer l'index manuellement
Si git reset échoue, vous pouvez supprimer le fichier d'index corrompu. Git le recréera automatiquement la prochaine fois qu'une commande (comme git status ou git add) en aura besoin.
Avertissement : La suppression de l'index effacera votre zone de staging. Toutes les modifications que vous aviez stagées (en utilisant git add) seront perdues.
# Supprimer le fichier d'index corrompu
rm .git/index
# Forcer Git à reconstruire l'index basé sur le répertoire de travail
# Ceci stage tous les fichiers actuellement modifiés
git add -A
# Vérifier l'état pour confirmer la fonctionnalité
git status
4. Gérer les objets brisés et manquants
Les corruptions impliquant des objets Git brisés (blobs, trees ou commits) sont souvent les plus difficiles à réparer, surtout si l'objet est véritablement manquant. Cependant, la corruption est parfois due à des objets mal empaquetés ou à des objets dangling (pendants) récupérables.
4.1. Réempaqueter le dépôt (Repackaging)
Git stocke les objets soit sous forme de fichiers libres, soit consolidés dans des fichiers pack. Parfois, l'exécution d'une opération de réempaquetage peut résoudre des problèmes d'intégrité mineurs et améliorer les performances.
# Réempaqueter tous les objets libres, vérifier l'intégrité et élaguer les anciens fichiers pack
git repack -a -d
# Réexécuter fsck pour confirmer l'amélioration
git fsck --full
4.2. Récupérer les commits dangling via Reflog
Un dangling commit (commit pendant) est un objet commit valide mais inaccessible par toute référence connue (branche, tag). Cela se produit souvent après des resets forcés ou des réécritures d'historique. Le reflog suit l'historique de votre HEAD local et de vos références, détenant souvent la clé de la récupération.
- Afficher le Reflog :
bash
git reflog
Recherchez le hachage SHA-1 précédant l'action qui a causé la perte (par exemple, HEAD@{5}: reset: moving to origin/main).
- Re-référencer le Commit :
Une fois que vous avez identifié le SHA-1 correct (par exemple, a1b2c3d4), vous pouvez créer une nouvelle branche pointant vers celui-ci, ou réinitialiser votre branche actuelle.
```bash
# Exemple : Créer une nouvelle branche de récupération
git branch recovered-work a1b2c3d4
# Alternativement, réinitialiser votre branche actuelle vers le commit dangling
# (Utiliser avec prudence)
git reset --hard a1b2c3d4
```
4.3. Que faire en cas d'objets véritablement manquants
Si git fsck signale une error: object XXXXX is missing, cela signifie que les données requises pour un historique de commit spécifique ne se trouvent plus dans votre base de données d'objets locale (.git/objects).
-
S'il existe une source distante : La seule solution fiable est de récupérer l'objet manquant à partir du dépôt distant.
```bash
git fetch originEnsuite, tenter de réparer le lien ou de réinitialiser la branche affectée
```
-
S'il n'existe aucune source distante (Corruption locale) : Si le dépôt est uniquement local et que l'objet est manquant, les données référencées par cet objet sont perdues de façon permanente, à moins que vous n'ayez une sauvegarde externe.
5. Réparer les références corrompues (Refs)
Les références (refs) sont les fichiers du répertoire .git/refs/ (par exemple, les branches, les tags, les branches de suivi distant) qui contiennent le hachage SHA-1 du commit vers lequel elles pointent. Si ces fichiers sont corrompus (par exemple, ils contiennent zéro octet ou des hachages invalides), Git ne peut pas déterminer l'état de vos branches.
5.1. Localisation et réparation manuelle
-
Identifier la ref corrompue : Le message d'erreur spécifie généralement quelle ref est brisée (par exemple,
error: bad ref for branch 'feature/X'). -
Naviguer vers le répertoire refs :
bash
cd .git/refs/heads/
# ou .git/refs/remotes/origin/
-
Inspecter le fichier : Utilisez un éditeur de texte ou
catpour visualiser le fichier. Il devrait contenir exactement 40 caractères hexadécimaux (le hachage SHA-1). -
Réparation :
- Si le hachage est connu (par exemple, grâce à
git reflog), collez manuellement le SHA-1 correct de 40 caractères dans le fichier. - Si la ref est clairement brisée (par exemple, zéro octet, données illisibles), supprimez le fichier. Vous devrez ensuite recréer la branche/ref si nécessaire (par exemple,
git checkout -b <branch-name> <known-good-commit>).
Bonne pratique : Suppression du Reflog
Si toute la base de données reflog semble corrompue, la suppression du dossier logs force Git à repartir de zéro, résolvant souvent les problèmes de référence graves.
rm -rf .git/logs
6. L'option de récupération finale : Cloner à partir d'une source saine connue
Si la corruption du dépôt est généralisée ou si les objets nécessaires sont manquants, la méthode de récupération la plus sûre et la plus fiable consiste à abandonner le dépôt local actuel et à le re-cloner à partir d'une source de confiance (généralement un serveur distant comme GitHub, GitLab ou Bitbucket).
# 1. Sauvegarder les modifications de travail du dépôt corrompu
# (par exemple, copier les fichiers non committés dans un emplacement temporaire)
# 2. Renommer ou supprimer le répertoire du dépôt corrompu
mv myrepo myrepo_bad
# 3. Cloner une copie fraîche
git clone <remote_url> myrepo
# 4. Appliquer les modifications de travail sauvegardées au nouveau dépôt
Cette méthode garantit que vous commencez avec une copie propre et validée de l'historique du dépôt, minimisant le risque de corruption persistante.
Résumé et Prévention
La réparation d'un dépôt Git corrompu nécessite un diagnostic minutieux à l'aide de git fsck avant d'appliquer des réparations ciblées à l'index, aux objets ou aux références. Donnez toujours la priorité à la sécurité en sauvegardant le répertoire .git avant de commencer. Bien que les méthodes de récupération locales comme git reflog soient puissantes pour récupérer l'historique, le clonage à partir d'un dépôt distant reste la solution la plus fiable en cas de corruption sévère.
Points clés à retenir :
- Sauvegardez d'abord. (Toujours).
- Diagnostiquez avec
git fsck --full. - Les problèmes d'index sont généralement résolus avec
git reset --hard. - Les objets manquants nécessitent généralement de faire un fetch à partir de la source distante.