37 votes

Comment puis-je réparer un dépôt avec une révision cassée ?

Mon serveur domestique a subi une panne de disque dur.

Une fois que j'ai réalisé que le disque était en train de lâcher, je me suis connecté et ai fait une copie directe de mon dépôt, qui contient plusieurs projets.

Cependant, comme le disque était défaillant, l'une des révisions est corrompue :

$ svnadmin verify master/
[...]
* Révision 820 vérifiée.
* Révision 821 vérifiée.
* Révision 822 vérifiée.
svnadmin : Aucune révision 823

Les répertoires master/db/revs/ et master/db/revprops/ ne contiennent effectivement aucun fichier appelé 823, donc cette révision manque (corrompue). Il y a des révisions ultérieures (que je veux vraiment conserver!) dans le dépôt master/ allant jusqu'à la révision n°947.

Aujourd'hui, j'ai récupéré ma sauvegarde externe la plus récente (!), qui inclut heureusement cette révision. Je voudrais "réparer" le dépôt corrompu dans master/ en fixant la révision manquante, puisqu'elle est plus récente que la sauvegarde.

J'ai veillé à charger le fichier de sauvegarde dans un dépôt nouvellement créé avec la même version que celui copié dans master/, donc il s'agit du format "linéaire" ancien 3.

J'ai essayé l'évidence, c'est-à-dire de simplement copier le fichier 823 des répertoires db/revs/ et db/revprops/ de la sauvegarde:

$ cp repos/db/revs/0/823 master/db/revs/
$ cp repos/db/revprops/0/823 master/db/revprops/

Le répertoire repos/ contient un dépôt qui a été chargé à partir de la sauvegarde. Maintenant j'obtiens :

$ svnadmin verify master/
[...]
* Révision 821 vérifiée.
* Révision 822 vérifiée.
svnadmin : /build/buildd/subversion-1.6.12dfsg/subversion/libsvn_delta/compose_delta.c:165: search_offset_index: Assertion `offset < ndx->offs[ndx->length]' échoué.
Abandon

Ce qui n'est pas très encourageant. J'ai essayé diverses autres commandes svnadmin, mais aucune n'a satisfait le vérificateur.

Mon idée suivante était de revenir en arrière dans la copie et de commencer avec une copie "fraîche" du dépôt corrompu, puis de sortir les révisions après 823 et de les fusionner avec la sauvegarde. Mais cela ne semble pas être possible, je ne peux pas sortir les révisions après celle manquante:

$ svnadmin dump -r 824 master/ >r824.dmp
svnadmin : Aucune révision 823

Notez que cela ne sert à rien de rendre la sauvegarde "incrémentielle", dans l'espoir de faire comme si le monde avait commencé avec la révision 824 et de continuer à partir de là :

$ svnadmin dump --incremental -r 824:947 master/ > dump.txt
svnadmin: Aucune révision 823

Cela écrit des résultats dans dump.txt, mais je ne suis pas sûr de pouvoir m'y fier. Notez qu'il ne mentionne pas qu'il a réussi à sauvegarder une seule révision.

Mise à jour : J'ai eu une autre idée : copier les fichiers de révision plus récents de la copie du disque défaillant dans master/ vers la sauvegarde, pour fournir la "queue manquante" :

$ for a in $(seq 910 947) ; do cp  master/db/revs/$a repos/db/revs ; cp master/db/revprops/$a repos/db/revprops/ ; echo $a ; done

Cependant, cela semble ne faire qu'endommager le dépôt cible :

$ svnadmin verify repos/
[...]
* Révision 907 vérifiée.
* Révision 908 vérifiée.
* Révision 909 vérifiée.
svnadmin : Représentation corrompue '907 21815 45 30922 158d3e72732f45bf6f02919b22fc899a'
svnadmin : En-tête de représentation malformée

Maintenant, je suis à court d'idées.

38voto

unwind Points 181987

J'ai résolu cela.

La solution était (bien sûr) évidente, une fois que j'ai réalisé.

J'avais ceci :

  • master/: Une copie d'un référentiel cassé, comprenant la révision 0..947, avec les fichiers de la révision 823 physiquement manquants.
  • repos/: Un référentiel chargé à partir d'une sauvegarde (fichier de vidage), couvrant la révision 0..910.

La solution était simplement de faire une vidange de master/, à partir de la révision 911 et au-delà. Cela a été possible sans aucune erreur, ce qui signifie que aucune des révisions dans la plage 911..947 ne dépendait directement de l'état de la révision 823, ou quelque chose comme ça :

$ svnadmin dump --incremental -r 911:947 master/ > tail.txt
* Révision vidangé 911.
* Révision vidangé 912.
* Révision vidangé 913.
[...]
* Révision vidangé 947.

De toute façon, il suffit ensuite d'appliquer la vidange au référentiel provenant de la sauvegarde :

$ cat tail.txt | svnadmin load repos/
[beaucoup de validations]

Et maintenant j'ai l'historique complet restauré, sans problèmes :

$ svnadmin verify repos/
* Révision vérifiée 0.
* Révision vérifiée 1.
* Révision vérifiée 2.
[...]
* Révision vérifiée 945.
* Révision vérifiée 946.
* Révision vérifiée 947.

Hourra !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X