Un dépôt git corrompu


Où l’on apprend qu’un dépôt git peut se corrompre

Un problème avec git

Aujourd’hui, il m’est arrivé un truc auquel je ne m’attendais pas.

Le disque dur sur lequel je bosse a décidé de partir en cacahuète.

Après un fcsk, tout est rentré dans l’ordre et j’ai repris mes sources, fait des modifications, des commit dans mon dépôt git de travail. Puis j’ai voulu pousser mes modifications vers mon serveur (celui qui fait toutes les sauvegardes entre autres). Et là, ce fut la surprise :

1
2
3
4
5
$ git push
error: inflate: data stream error (incorrect header check)
error: corrupt loose object ’d9a64402f258808439c7651ea1993cffad6496a6’
fatal: object d9a64402f258808439c7651ea1993cffad6496a6 is corrupted
fatal: The remote end hung up unexpectedly

Il existe la commande git fsck qui peut, parfois, rétablir les choses. Si c’est le cas, youpi, vous avez gagné, faites des sauvegardes et payez-vous un bon restau.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ git fsck --full
error: sha1 mismatch 1259337b18a9175cdbdbdfdb7eb84b532e69f02c

error: 1259337b18a9175cdbdbdfdb7eb84b532e69f02c: object corrupt or missing
error: sha1 mismatch 16ec865233c2255a2dad5eb6193560c2bf69bdde

error: 16ec865233c2255a2dad5eb6193560c2bf69bdde: object corrupt or missing
error: sha1 mismatch bbf88a84e284d57690e053b922f6f6e60629af11

error: bbf88a84e284d57690e053b922f6f6e60629af11: object corrupt or missing
error: inflate: data stream error (incorrect header check)
error: corrupt loose object ’d9a64402f258808439c7651ea1993cffad6496a6’
fatal: object d9a64402f258808439c7651ea1993cffad6496a6 is corrupted

Si ce n’est pas le cas, vous entrez, comme moi, dans la désespérance la plus totale.

Heureusement, il y a une solution simple (on trouve sur le net plein de solutions compliquées, celle que je vous propose, dont je ne suis que l’interprète est donc facile à mettre en oeuvre).

Un autre clone du dépôt

On commence par faire un autre clone du dépôt de référence, celui vers lequel vous vouliez pousser vos modifications, dans un répertoire provisoire.

1
$ git clone ssh://server/path/to/repo.git

Copie des d’éléments sains.

Nous allons copier la base des objects du dépôt sain vers le dépôt malade.

1
2
$ cd /path/to/old/repo
$ echo /tmp/repo/.git/objects > .git/objects/info/alternates

Utilisation de notre sauvegarde

Et nous allons utiliser la commande git repack qui va utiliser la sauvegarde (car c’est en fait dans un répertoire de sauvegarde que nous avons fait notre copie) pour reconstituer la base.

1
2
3
4
5
6
$ git repack -a -d
Counting objects: 8995, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2630/2630), done.
Writing objects: 100% (8995/8995), done.
Total 8995 (delta 6328), reused 8891 (delta 6232)

Petite vérification

Pour être sur j’ai refait un git fsck

1
2
3
4
$ git fsck --full
dangling commit d9a64402f258808439c7651ea1993cffad6496a6
dangling commit 502e09e091dea489b36e9cf091277ee3a8907fca
dangling blob 24505e89c925e7df54dbeae44fd651afa0790dc2

Un dépôt tout beau

Voilà, nous avons maintenant un dépôt tout beau, tout propre, prêt à servir.

1
2
3
4
5
$ git status
# On branch hotfix/1.1.7.1
# Your branch is ahead of 'origin/hotfix/1.1.7.1'  by 2 commits.
#
nothing to commit (working directory clean)

Et je peux pousser mes modifications.

1
2
3
4
5
6
$ git push
From ssh://server/path/to/repo.git
   2070cf3..d9a6440  hotfix/1.1.7.1 -> origin/hotfix/1.1.7.1
Merge made by recursive.
 Projects/Classes/dummy.m |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

On peux maintenant supprimer le dépôt provisoire.

powered by FreeBSD