Illustration: Un script de déduplication défectueux supprime des fichiers ; récupération via dépôt Git, miroir Nextcloud et sauvegarde

Ce compte rendu d'expérience résume un incident survenu lors de la consolidation d'un important volume de documents financiers et fiscaux. Il est anonymisé, mais suit exactement la chaîne d'erreurs technique. L'objectif est de permettre aux exploitants de partages SMB, de miroirs Nextcloud et de dépôts Git d'éviter de commettre les mêmes erreurs.

Situation de départ

Un travailleur indépendant dans le domaine de la recherche et du freelance souhaitait transférer ses documents financiers accumulés au fil des années depuis un partage source (Samba/NAS) vers une nouvelle structure cible organisée par années (dossiers FY2015FY2026 ainsi que FY_undatiert). La source contenait des copies fortement redondantes ; en conclusion, une déduplication (« aucun fichier en double ») était prévue.

Ce qui a mal tourné

Deux erreurs se sont combinées pour provoquer une perte de données massive :

  1. Aucune sauvegarde vérifiée avant le début. Ce n'est qu'a posteriori qu'une sauvegarde externe de 8 To (du 16.08.) a été montée. Si elle avait été vérifiée au préalable, l'erreur suivante aurait eu peu d'impact.
  2. Un script de déduplication avec une liste de chemins non quotée. La liste des répertoires à parcourir a été transmise sans guillemets à find. Comme certains chemins contenaient des espaces (par ex. Freigabe/Banken/Konto 1234 5678/2024), le shell a découpé ces chemins. Cela a fait en sorte que les répertoires parents et enfants apparaissaient plusieurs fois comme points de départ — find a listé le même fichier plusieurs fois.

Le script de déduplication comparait les hachages SHA-256 consécutifs et supprimait la seconde entrée « identique ». Comme le même fichier, en raison de la liste multiple, apparaissait comme « duplicat » de lui-même, il a été supprimé — ainsi que toutes les autres occurrences. Des fichiers uniques ont été détruits, pas des copies redondantes.

flowchart TD A["Verzeichnisliste SCOPE unquotiert
(find $SCOPE)"] --> B["Shell trennt Pfade mit
Leerzeichen in Fragmente"] B --> C["Eltern- und Kindverzeichnisse
erscheinen mehrfach als Startpunkte"] C --> D["find listet dieselbe Datei
N-mal (N > 1)"] D --> E["Dedup: aufeinanderfolgende
Hash-Werte vergleichen"] E --> F["h == prev bei wiederholter
Listung derselben Datei"] F --> G["rm der 'Duplikate' =
Löschung einzigartiger Dateien"] G --> H["~6.400 einzigartige Dateien
vernichtet"] style G fill:#c0392b,color:#fff style H fill:#c0392b,color:#fff

La récupération

Dès que l'erreur a été détectée, l'opération en cours a été immédiatement arrêtée. Il n'existait pas de dépôt Git local comme source, mais trois autres copies existaient sur le serveur ou en externe :

flowchart LR D["Gelöschte Dateien
(~6.400)"] --> M["Nextcloud-Sync-Spiegel
der Quelle"] D --> Z["Überlebende ZIP-Archive"] D --> B["Externes 8-TB-Backup
(16.08.)"] D --> G["Git-Origin (Gitea)
für Teil-Repo"] M -->|"~5.300"| R["Wiederhergestellt"] Z -->|"~70"| R B -->|"~600"| R G -->|"History"| R R --> S["~98 % gerettet
(~6.300 von ~6.400)"] style S fill:#27ae60,color:#fff

Au total, environ 98 % des fichiers supprimés ont pu être restaurés. Les ~2 % restants concernaient des fichiers qui n'existaient dans aucune des copies disponibles (notamment une exportation de boîte mail et quelques documents créés après la sauvegarde).

Pourquoi le concept GitCover est utile ici

Cette histoire montre : quiconque mise sur des structures natives Git retrouve rapidement une capacité de travail après une erreur involontaire — et documente simultanément de manière conforme aux GoBD.

Les dépôts Git comme filet de sécurité. Un commit transforme les fichiers de travail non versionnés en éléments de l'historique. Une suppression ou une surcharge accidentelle (y compris par un script) peut être restaurée à tout moment depuis le dépôt — on peut continuer à travailler au lieu de repartir de zéro.
GoBD, RGPD et NIS2 apaisés. Les obligations légales — conservation GoBD, preuves RGPD ou notifications NIS2 — se documentent proprement grâce à des artefacts versionnés et traçables. Un incident devient un événement protocolisé et reproductible plutôt qu'un problème insoluble.
Des agents IA lâchés sur des données. Même lors de l'utilisation d'agents accédant automatiquement aux données, les concepts de base de GitCover aident : une provenance claire (SHA-256), un historique immuable et des copies indépendantes (miroir, sauvegarde, origine) limitent les dégâts et rendent chaque action révisable.

Leçons apprises

Conclusion : Un simple appel de variable non quoté suffit à détruire des milliers de fichiers uniques. La récupération n'a été possible que parce que plusieurs copies indépendantes existaient. La structure, le processus et la discipline ne sont pas des sujets de luxe — ce sont la seule protection qui existe.

Partie de la rubrique Expériences. D'autres articles à suivre.