16 points par GN⁺ 2026-01-29 | Aucun commentaire pour le moment. | Partager sur WhatsApp
  • Pour mieux comprendre la structure interne d’un système de gestion de versions, l’auteur a implémenté lui-même un système similaire à Git
  • Il remplace le hachage SHA-1 et la compression zlib de Git par un hachage SHA-256 et la compression zstd, avec un dépôt structuré autour du répertoire .tvc
  • Écrit en Rust, le projet implémente étape par étape les fonctions de hachage de fichiers, compression, commit et checkout
  • Les objets de commit incluent le hash de l’arbre, le commit parent, l’auteur et le message, et un même fichier n’est pas réenregistré si son hash existe déjà
  • L’expérience met en évidence que Git est un stockage de fichiers adressé par le contenu, et souligne l’importance d’un format de données structuré

Méthodes de hachage et de compression

  • Git identifie tous les objets par un hachage SHA-1, mais ce projet utilise SHA-256
    • SHA-1 est ancien et présente des faiblesses de sécurité, mais ici la sécurité n’était pas essentielle puisqu’il s’agissait simplement d’identifier le contenu des fichiers
  • À la place de zlib, le projet adopte zstd de Facebook comme bibliothèque de compression
    • zstd a été jugé plus efficace, et la compatibilité avec Git n’était pas un objectif
  • Le projet s’appelle « tvc (Tony’s Version Control) », et utilise les fichiers .tvc et .tvcignore comme équivalents de la structure Git

Étapes d’implémentation

  • La procédure d’implémentation suit l’ordre suivant : lecture des arguments de commande → lecture des règles d’exclusion → affichage de la liste des fichiers → hachage et compression → création des arbres et commits → gestion de HEAD → checkout d’un commit
  • Écrit en Rust, la commande ls applique les règles de .tvcignore, parcourt récursivement les fichiers non ignorés et affiche le hachage SHA-256 de chaque fichier
  • Les fonctions de compression et décompression de fichiers ont été implémentées simplement à l’aide de la bibliothèque zstd

Structure des commits

  • Un objet de commit contient les informations suivantes
    1. le type d’objet (« commit »)
    2. l’état du système de fichiers à cet instant (hash de l’arbre)
    3. le commit précédent (HEAD)
    4. l’auteur (author)
    5. le message de commit
  • Contrairement à Git, le projet ne distingue pas auteur et committer, et n’implémente ni fusion ni rebase
  • Lors de la création d’un commit, un objet arbre est généré, haché, compressé puis stocké dans .tvc/objects/, avant mise à jour du fichier HEAD
  • Si deux fichiers ont le même hash, ils ne sont pas stockés une seconde fois, ce qui permet d’éviter les doublons

Objets arbre et checkout

  • La fonction generate_tree() parcourt les répertoires, hache, compresse et stocke chaque fichier, puis construit une chaîne contenant le nom de fichier et son hash
    • Les sous-répertoires sont traités récursivement pour former une structure en arbre
  • Les objets commit et arbre sont analysés sous forme de structures (Commit, Tree) afin d’être plus faciles à manipuler en mémoire
  • La fonction generate_fs() reconstruit le système de fichiers à partir de la structure d’arbre et effectue le checkout dans le chemin spécifié

Enseignements du projet

  • Le projet permet de constater directement que Git est un stockage de fichiers adressé par le contenu (key-value)
  • La partie la plus difficile a été l’analyse du format des objets ; l’auteur prévoit d’utiliser la prochaine fois un format plus explicite comme YAML ou JSON
  • Le code complet est publié sur GitHub (tonystr/t-version-control)

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.