web-dev-qa-db-fra.com

Comment réparer un référentiel 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 allait, je me suis connecté et j'ai fait une copie directe de mon référentiel, qui contient plusieurs projets.

Cependant, comme le disque échouait, l'une des révisions est interrompue:

$ svnadmin verify master/
[...]
* Verified revision 820.
* Verified revision 821.
* Verified revision 822.
svnadmin: No such revision 823

Le master/db/revs/ et master/db/revprops/ les répertoires ne contiennent en effet aucun fichier appelé 823, donc cette révision est manquante (cassée). Il y a des révisions ultérieures (que je veux vraiment garder!) Dans le master/ dépôt allant jusqu'à la révision # 947.

Aujourd'hui, j'ai récupéré ma dernière sauvegarde hors site (!), Qui inclut heureusement cette révision. Je voudrais "guérir" le référentiel cassé dans master/ en corrigeant la révision manquante, car elle est plus récente que la sauvegarde.

Je me suis assuré de charger le fichier de vidage dans un référentiel nouvellement créé avec la même version que celui copié dans master/, c'est donc tout l'ancien format "linéaire" 3.

J'ai essayé l'évidence, juste copier le fichier 823 à partir de la sauvegarde db/revs/ et db/revprops/ répertoires:

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

Le répertoire repos/ contient un référentiel qui a été chargé à partir du vidage de sauvegarde. Maintenant je reçois:

$ svnadmin verify master/
[...]
* Verified revision 821.
* Verified revision 822.
svnadmin: /build/buildd/Subversion-1.6.12dfsg/Subversion/libsvn_delta/compose_delta.c:165: search_offset_index: Assertion `offset < ndx->offs[ndx->length]' failed.
Aborted

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

Mon idée suivante était de revenir sur la copie et de commencer avec une copie "fraîche" du référentiel cassé, puis de vider les révisions après 823 et de fusionner avec la sauvegarde. Mais cela ne semble pas possible, je ne peux pas vider les révisions après celle qui manque:

$ svnadmin dump -r 824 master/ >r824.dmp
svnadmin: No such revision 823

Notez que cela n'aide pas à rendre le vidage "incrémentiel", dans l'espoir qu'il devrait prétendre que le monde a commencé avec la révision 824 et simplement partir de là:

$ svnadmin dump --incremental -r 824:947 master/ > dump.txt
svnadmin: No such revision 823

Cela écrit la sortie dans dump.txt, mais je ne sais pas si on peut s'y fier. Notez qu'il ne consigne pas qu'il a réussi à vider toute révision .

Mise à jour: J'ai eu une autre idée: copier les fichiers de révision les plus récents à partir de la copie du disque en panne dans master/ dans 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 que corrompre le référentiel cible:

$ svnadmin verify repos/
[...]
* Verified revision 907.
* Verified revision 908.
* Verified revision 909.
svnadmin: Corrupt representation '907 21815 45 30922 158d3e72732f45bf6f02919b22fc899a'
svnadmin: Malformed representation header

Maintenant, je n'ai plus d'idées.

36
unwind

Je l'ai résolu.

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

J'avais ceci:

  • master/: Une copie d'un référentiel cassé, avec 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 vider de master/, à partir de la révision 911. Cela a été possible sans aucune erreur, ce qui, je suppose, signifie qu'aucune des révisions de 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
* Dumped revision 911.
* Dumped revision 912.
* Dumped revision 913.
[...]
* Dumped revision 947.

Quoi qu'il en soit, il suffit alors d'appliquer le vidage au référentiel provenant de la sauvegarde:

$ cat tail.txt | svnadmin load repos/
[lots of commits]

Et maintenant, j'ai tout l'historique restauré, pas de problème:

$ svnadmin verify repos/
* Verified revision 0.
* Verified revision 1.
* Verified revision 2.
[...]
* Verified revision 945.
* Verified revision 946.
* Verified revision 947.

Yay!

37
unwind