Introduction
git fetch est l'opération réseau qui télécharge de nouveaux objets et met à jour les refs de tracking distant. Il ne change pas vos branches ou arborescence de travail, ce qui en fait la commande « quoi de neuf ? » la plus sûre.
La séquence
- Résoudre l'URL du remote.
- Ouvrir une connexion (HTTPS, SSH ou git://).
- Négocier les capacités (version de protocole, multi-ack, filtres de clone partiel, etc.).
- Le serveur annonce les refs (ou, en protocole v2, seulement celles correspondant aux motifs demandés).
- Le client signale ce qu'il a déjà.
- Le serveur envoie un pack file contenant les objets manquants.
- Le client écrit le pack dans
.git/objects/pack/et l'indexe. - Le client met à jour les refs de tracking distant (
refs/remotes/origin/*). - Optionnellement élague les refs supprimées.
Commandes
git fetch
git fetch origin
git fetch --all
git fetch --prune
git fetch origin main:my-main # fetch dans une ref locale
La syntaxe deux-points main:my-main crée ou met à jour directement une ref locale ; à utiliser avec précaution.
Inspecter ce qui a été fetché
git fetch origin
cat .git/FETCH_HEAD
git log HEAD..origin/main --oneline
FETCH_HEAD liste chaque ref mise à jour par le fetch le plus récent, dans l'ordre demandé.
Refspecs
Chaque remote a un ou plusieurs refspecs de fetch. Le défaut pour origin :
+refs/heads/*:refs/remotes/origin/*
Vous pouvez en ajouter d'autres, par exemple pour fetcher les refs de pull-request depuis GitHub :
git config --add remote.origin.fetch '+refs/pull/*/head:refs/remotes/origin/pr/*'
git fetch
git switch -c review/123 origin/pr/123
Élaguer
Sans prune, les branches supprimées sur le serveur subsistent comme des refs origin/* obsolètes :
git fetch --prune
git config --global fetch.prune true
Tags
Par défaut, fetch télécharge les tags pointant vers les commits fetchés. Forcer ou désactiver :
git fetch --tags
git fetch --no-tags
Trace et debug
GIT_TRACE=1 GIT_TRACE_PACKET=1 git fetch
GIT_CURL_VERBOSE=1 git fetch # HTTPS
Cela révèle les requêtes exactes, utile pour déboguer les proxys ou l'authentification.
Négociation et haves
Le handshake de fetch est une danse de « wants » et « haves ». Le client liste ce qu'il veut (les SHAs des pointes des branches distantes) et offre ses haves (commits locaux récents) pour que le serveur calcule un pack minimal. Git moderne utilise l'algorithme de négociation skipping, qui converge en O(log n) tours même sur de longs historiques. Vous pouvez l'ajuster :
git config fetch.negotiationAlgorithm skipping
git config fetch.negotiationAlgorithm consecutive
GIT_TRACE_PACKET=1 git fetch 2>&1 | grep -E 'have|want' | head
Erreurs fréquentes
Croire que git fetch change vos branches ; il ne le fait jamais. Utilisez git pull ou git merge origin/main pour intégrer. Sauter --prune dans les clones de longue durée et accumuler des dizaines de refs origin/* obsolètes. Mal configurer un refspec à la main et écraser des branches locales ; double-vérifiez avec git config -e. Enfin, fetcher depuis un clone partiel sans réaliser que certains objets nécessiteront un appel réseau de suivi à l'accès ; les clones partiels échangent une rapidité initiale contre une latence occasionnelle plus tard.