Tutoriel Git (Markdown) — Cloner les métadonnées sans contenu, comprendre index vs working tree, corriger un état “deleted + untracked”

Ce tutoriel synthétise les usages de Git nécessaires pour : (1) récupérer uniquement les métadonnées d’un dépôt (historique, refs, objets) sans “checkout” de fichiers, (2) diagnostiquer l’état “des fichiers sont marqués supprimés mais existent en non suivis”, (3) remettre le dépôt dans un état cohérent selon l’intention. Le fil conducteur est la compréhension correcte de la triade HEAD / index / working tree et de ce que font réellement clone, checkout, reset, restore, clean, et le partial clone.

1) Modèle mental minimal : HEAD, index, working tree

Git n’est pas “un dossier qui contient des fichiers”. C’est trois couches distinctes :

  • HEAD : la révision courante (un commit). C’est une photo immuable de l’état versionné.
  • Index (staging area) : la zone de préparation. C’est ce que Git s’apprête à valider dans un prochain commit.
  • Working tree : les fichiers présents sur disque, éditables.

git status compare :

  • HEAD vs index (ce qui est “staged”)
  • index vs working tree (ce qui est “modified” ou “deleted” non staged) et liste aussi les fichiers untracked (présents sur disque mais inconnus de l’index).

Conséquence clé : il est possible d’avoir, simultanément, un fichier “deleted” dans l’index (staged) et un fichier physiquement présent mais “untracked”, si l’entrée d’index ne pointe plus vers ce fichier (ou a été retirée) alors que le disque contient une copie apparue hors du contrôle Git.

2) Récupérer uniquement le dépôt Git sans télécharger le contenu des fichiers

Objectif : récupérer historique, branches, tags, commits, arborescence, mais éviter de remplir le disque avec les fichiers (blobs). Trois méthodes pratiques, selon le besoin.

Méthode 1 — --bare : dépôt nu (équivalent d’un .git isolé)

git clone --bare https://huggingface.co/PaddlePaddle/PaddleOCR-VL-1.5.git

Effet :

  • crée un répertoire PaddleOCR-VL-1.5.git/
  • contient objets, refs, hooks, config
  • aucun working tree, donc aucun checkout possible dans ce répertoire sans manipulation supplémentaire

Usage typique :

  • miroir, infra, CI, synchronisation, serveur Git, analyse d’historique, sauvegarde
  • on ne modifie pas des fichiers “dans” ce dépôt, on l’utilise comme base d’objets et de refs

Commandes utiles dans un bare :

git --git-dir=PaddleOCR-VL-1.5.git log --oneline --decorate --graph --all
git --git-dir=PaddleOCR-VL-1.5.git show refs/heads/main
git --git-dir=PaddleOCR-VL-1.5.git branch -a

Méthode 2 — --no-checkout : dépôt standard, working tree vide

git clone --no-checkout https://huggingface.co/PaddlePaddle/PaddleOCR-VL-1.5.git

Effet :

  • crée un répertoire de travail
  • .git/ complet
  • pas d’extraction des fichiers tant que tu n’as pas demandé explicitement un checkout

Ce mode est utile si tu veux un dépôt “normal” (avec remote, config locale, etc.) tout en gardant le disque vide au départ.

Pour vérifier ce qui est disponible sans checkout :

cd PaddleOCR-VL-1.5
git branch -a
git log --oneline --decorate -n 20
git ls-tree -r --name-only origin/main | head

Méthode 3 — partial clone : --filter=blob:none --no-checkout

git clone --filter=blob:none --no-checkout https://huggingface.co/PaddlePaddle/PaddleOCR-VL-1.5.git

Effet :

  • télécharge commits, trees, refs (structure)
  • n’importe pas les blobs (contenu des fichiers) tant que pas nécessaire
  • permet un accès “à la demande” quand une commande requiert le contenu

Exemples :

cd PaddleOCR-VL-1.5
git ls-tree -r --name-only origin/main | head
git show origin/main:README.md   # peut déclencher un téléchargement paresseux du blob

Pour extraire seulement un sous-répertoire (avec blob téléchargés seulement pour ce chemin) :

git sparse-checkout init --cone
git sparse-checkout set docs
git checkout main

Point important : --filter=blob:none réduit fortement le volume initial, mais certaines opérations (checkout complet, diff de gros fichiers, etc.) déclencheront des téléchargements.

3) Comprendre l’état “deleted (staged) + untracked (présents sur disque)”

Symptôme typique dans git status :

  • une section “Changes to be committed” avec des fichiers marqués deleted: ...
  • une section “Untracked files” listant… ces mêmes chemins ou des fichiers équivalents

Lecture exacte :

  • l’index contient des entrées où ces chemins sont enregistrés comme supprimés (donc la prochaine validation supprimerait ces fichiers du dépôt)
  • le working tree contient des fichiers qui ne correspondent pas aux entrées index (donc Git les voit comme nouveaux et non suivis)

Ce n’est pas une contradiction : cela signifie que l’index et le disque ne racontent pas la même histoire.

Causes fréquentes (génériques, sans supposer un outil précis) :

  • manipulation du working tree par un outil externe (téléchargement, extraction, copie) dans le répertoire du dépôt
  • un checkout partiel / sparse-checkout / no-checkout suivi d’une injection de fichiers hors Git
  • nettoyages ou scripts qui ont altéré l’index (ex: git rm --cached ou reset partiel), puis réapparition de fichiers sur disque par copie

Diagnostic rapide et factuel :

  1. Voir ce qui est réellement “staged” (HEAD vs index) :
git diff --cached --name-status
  1. Voir ce qui diffère entre index et disque :
git diff --name-status
  1. Voir si un fichier est connu de l’index :
git ls-files --stage -- chemin/vers/fichier
  • si aucune sortie : il est untracked (du point de vue index)
  • si sortie : il est suivi (et un deleted staged se verra par diff cached)
  1. Voir l’historique d’un chemin :
git log --oneline -- chemin/vers/fichier | head

4) Corriger selon l’intention

Les commandes ci-dessous sont des “axes” : tu choisis en fonction de l’objectif. Ne mélange pas sans comprendre l’effet sur HEAD/index/disque.

Cas A — Revenir strictement à origin/main (remise à zéro locale)

Objectif : retrouver exactement la révision distante, supprimer toutes modifications locales et tous fichiers non suivis.

git fetch origin
git reset --hard origin/main
git clean -fd

Effets :

  • reset --hard : HEAD et index pointent sur origin/main, le working tree est réécrit pour correspondre
  • clean -fd : supprime fichiers non suivis et répertoires non suivis

Variante plus agressive (efface aussi les fichiers ignorés) :

git clean -fdx

Cas B — Garder les fichiers présents sur disque, annuler les suppressions staged, et les remettre sous suivi

Objectif : l’état actuel sur disque est le bon, et tu veux que Git arrête de préparer des suppressions + recommence à suivre.

git restore --staged .
git add .
git status

Effets :

  • restore --staged . : remet l’index en accord avec HEAD (annule le staging des suppressions)
  • add . : (re)indexe ce qui est sur disque ; les fichiers deviennent suivis/staged selon leur statut

À faire si tu veux ensuite commit :

git commit -m "Rétablir les fichiers et resynchroniser l’index"

Cas C — Annuler uniquement le “staging deleted”, sans toucher au disque

Objectif : juste faire disparaître la section “deleted” dans “to be committed”, sans réécrire les fichiers.

git restore --staged .
git status

Effet :

  • l’index revient à HEAD pour ces chemins
  • les fichiers restent sur disque, et s’ils ne sont pas suivis, ils resteront “untracked” tant que tu ne fais pas git add

Cas D — Tu voulais uniquement les métadonnées, pas de working tree : nettoyer et verrouiller le flux

Objectif : aucun fichier projet sur disque, juste l’historique/réfs.

Option 1 (repartir proprement en bare) :

rm -rf PaddleOCR-VL-1.5
git clone --bare https://huggingface.co/PaddlePaddle/PaddleOCR-VL-1.5.git

Option 2 (garder un clone non-bare mais sans fichiers) :

git reset --hard
git clean -fd

Puis éviter tout outil qui écrit dans ce répertoire.

5) Contrôles de cohérence après correction

Après l’une des solutions :

  • git status doit être lisible et cohérent (soit clean, soit modifications explicites)
  • vérifier la branche et le HEAD :
git branch --show-current
git rev-parse --short HEAD
  • vérifier que l’index correspond à HEAD (aucune diff cached) :
git diff --cached --name-status
  • si partial clone : vérifier la config et comprendre les téléchargements paresseux :
git config --get remote.origin.promisor
git config --get remote.origin.partialclonefilter

6) Résumé opératoire (règles pratiques)

  1. Si l’objectif est “uniquement .git”, utilise git clone --bare et ne travaille pas dans un répertoire de working tree.
  2. --no-checkout donne un dépôt normal sans extraction : utile pour inspecter branches/commits/trees sans écrire les fichiers.
  3. --filter=blob:none réduit le coût initial ; le contenu se télécharge lors des opérations qui en ont besoin.
  4. “deleted staged + untracked présents” = index et disque désynchronisés. Diagnostic avec git diff --cached, git ls-files.
  5. Correction minimale : git restore --staged .. Remise à zéro totale : git reset --hard origin/main && git clean -fd. Reprise sous suivi : git restore --staged . && git add ..