Introduction
Un clone shallow télécharge seulement les N derniers commits d'une branche au lieu de l'historique complet. Le résultat est beaucoup plus petit et plus rapide à fetcher, au prix d'un historique incomplet.
Créer
git clone --depth 1 https://github.com/example/widget.git
git clone --depth 50 https://github.com/example/widget.git
git clone --depth 1 --branch v1.2.3 --single-branch <url>
Le répertoire .git contient un fichier shallow listant les commits dont les parents ont été omis.
Pourquoi shallow
- Builds CI : besoin seulement de la source pour HEAD.
- Conteneurs et Dockerfiles : images plus petites.
- Outils ponctuels qui n'ont pas besoin d'historique.
Limitations
- Vous ne pouvez pas pousser depuis un clone shallow si votre push dépend de commits que le serveur n'a pas (rare, mais possible).
git logs'arrête à la frontière shallow.- Certaines opérations (rebase à travers la frontière, blame sur de vieilles lignes) ne peuvent pas fonctionner.
- Jusqu'à Git 2.11, le clonage shallow via HTTP n'était pas supporté ; Git moderne le gère.
Approfondir et désinitialiser le shallow
git fetch --depth 100 # étendre la profondeur
git fetch --deepen 50 # ajouter 50 commits de plus
git fetch --shallow-since=2024-01-01
git fetch --unshallow # télécharger tout l'historique
Après --unshallow, le dépôt se comporte comme un clone normal.
Single-branch et shallow
--single-branch + --depth 1 est le plus petit clone utile possible. Pour ensuite suivre d'autres branches :
git remote set-branches --add origin main feature
git fetch origin
Clones partiels (une optimisation différente)
Si vous avez besoin de l'historique complet mais pas de tous les blobs, utilisez plutôt un clone partiel :
git clone --filter=blob:none <url>
git clone --filter=tree:0 <url>
Les clones partiels téléchargent l'historique mais reportent les blobs (ou trees) jusqu'à besoin. Ils sont généralement un meilleur choix que shallow quand le serveur les supporte.
Détecter l'état shallow
git rev-parse --is-shallow-repository
cat .git/shallow
Patrons CI
De nombreux fournisseurs de CI font des clones shallow par défaut (depth 1 ou 50). Si votre build exécute git describe ou a besoin de blame entre versions, demandez un clone complet :
# GitHub Actions
- uses: actions/checkout@v4
with:
fetch-depth: 0
Fichiers shallow et grafts
Le fichier shallow dans .git/ liste les SHAs de commits dont les parents sont intentionnellement manquants. Git les traite comme des racines pendant la traversée du graphe. Le mécanisme connexe mais déprécié info/grafts permettait de fausser les relations parent ; utilisez plutôt git replace --graft, qui est plus sûr et se réplique via fetch :
cat .git/shallow
git replace --graft <commit> <new-parent>
git replace -l
git replace -d <commit>
Cela est occasionnellement utile pour assembler des historiques importés sans réécrire les commits.
Erreurs fréquentes
Exécuter git describe dans un clone depth-1 et obtenir une erreur parce qu'aucun tag annoté n'est atteignable ; soit fetchez les tags (--tags) soit utilisez un clone plus profond. Essayer de rebaser une branche de feature dans un clone shallow où la base de merge est au-delà de la frontière shallow ; approfondissez d'abord. Pousser depuis un clone shallow et être surpris par « remote rejected » ; le serveur peut avoir besoin d'objets parents manquants. Enfin, traiter les clones shallow comme un substitut aux clones partiels ; ils résolvent des problèmes différents et le partiel est généralement plus convivial.