origin/main n'est pas une branche distante : c'est un marqueur
local mis à jour par git fetch. Cette confusion est la source de
nombreuses erreurs, branches qui « ne se mettent pas à jour », pushs
rejetés, upstreams manquants. Ce guide vous explique la mécanique des
branches distantes, vous montre comment les synchroniser, lire leur
état et configurer vos upstreams correctement.
Prérequis : Les branches Git en bref et Merge et résolution de conflits.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre
origin/mainet le mécanisme de tracking branch - Distinguer
fetchetpullpour synchroniser votre dépôt local - Pousser une branche locale vers le remote et configurer le suivi
- Supprimer une branche distante proprement après fusion
Les 3 types de branches à ne pas confondre
Section intitulée « Les 3 types de branches à ne pas confondre »Les trois lignes du tableau désignent des objets de nature différente, et
c'est là que naît la confusion. Les deux premières sont des pointeurs
stockés dans votre dépôt local : main et origin/main vivent tous les
deux sur votre disque, dans .git/refs/. La troisième n'est pas un pointeur
du tout, c'est une relation enregistrée dans .git/config qui dit à Git
quelle référence distante comparer à quelle branche locale. Retenez la colonne
« Modifiable ? » : elle explique pourquoi un commit sur origin/main est
impossible.
| Type | Exemple | Description | Modifiable ? |
|---|---|---|---|
| Branche locale | main, feature/login | Pointeur sur vos commits locaux | Oui |
| Référence distante | origin/main, origin/develop | Copie locale de l'état du remote, mise à jour par fetch | Non (lecture seule) |
| Upstream | origin/main lié à main | Le remote + branche que suit votre branche locale | Ce n'est pas un pointeur |
Concrètement :
Votre machine Serveur (GitHub)───────────────────────────── ─────────────────main → commit A main → commit Aorigin/main → commit A (copie locale, mise à jour par fetch)
Après git fetch (quelqu'un a pushé B sur le serveur) :main → commit A main → commit Borigin/main → commit B ← la copie est mise à jour votre main est en retard de 1 commitQue se passe-t-il lors d'un git clone ?
Section intitulée « Que se passe-t-il lors d'un git clone ? »Quand vous clonez un dépôt, Git :
- Télécharge tous les objets (commits, arbres, blobs)
- Crée des références distantes pour chaque branche du remote
(ex.
origin/main,origin/develop) - Crée une branche locale
mainqui suitorigin/main - Vous place sur
main
Remote (GitHub) : Local après clone :main → C3 origin/main → C3develop → C5 origin/develop → C5 main → C3 (tracking origin/main) HEAD → mainLe nom origin est la convention par défaut pour le remote principal.
Ce n'est qu'un alias configurable.
Références distantes : origin/branch
Section intitulée « Références distantes : origin/branch »Les branches de forme origin/main, origin/develop sont des
remote-tracking branches. Elles sont en lecture seule : vous ne
pouvez pas faire de commit dessus directement.
# Voir toutes les branches (locales + distantes)git branch -aSortie :
* main feature/auth remotes/origin/main remotes/origin/develop remotes/origin/feature/authLes remotes/origin/... sont les références distantes. Elles sont
mises à jour uniquement par git fetch ou git pull.
git fetch : récupérer sans fusionner
Section intitulée « git fetch : récupérer sans fusionner »git fetch télécharge les nouveaux commits du remote et met à jour
les références distantes, sans modifier vos branches locales :
git fetch originAvant fetch : Après fetch :origin/main → C3 origin/main → C5 (mis à jour)main → C3 + C4 (local) main → C3 + C4 (inchangé)Votre branche main locale n'a pas bougé. Pour intégrer les
changements distants :
# Option 1 : mergegit merge origin/main
# Option 2 : rebase (historique linéaire)git rebase origin/maingit fetch vs git pull
Section intitulée « git fetch vs git pull »La seule vraie différence tient dans la troisième colonne. git pull n'est pas
une commande plus complète que git fetch, c'est git fetch suivi
immédiatement d'une opération d'intégration que vous n'avez pas vue arriver.
La conséquence pratique est qu'un git pull peut vous déposer en plein
conflit de fusion alors que vous vouliez seulement savoir si le remote
avait bougé. Le comportement de git pull dépend aussi de la configuration
pull.rebase, ce qui rend son effet dépendant de la machine sur laquelle on
travaille.
| Commande | Action | Modifie la branche locale ? |
|---|---|---|
git fetch | Télécharge les commits distants | Non |
git pull | git fetch + git merge | Oui |
git pull --rebase | git fetch + git rebase | Oui |
Tracking branches
Section intitulée « Tracking branches »Une tracking branch (branche de suivi) est une branche locale liée à une branche distante. Cette liaison permet à Git d'afficher des informations comme « 2 commits d'avance, 1 commit de retard ».
Créer une tracking branch
Section intitulée « Créer une tracking branch »Le cas courant est celui d'un collègue qui a poussé une branche que vous
voulez reprendre. Après un git fetch, la référence origin/feature/api
existe chez vous mais aucune branche locale ne lui correspond. Les deux
commandes ci-dessous créent cette branche locale et enregistrent le lien en
une seule opération ; la seconde n'est possible que si un seul remote
possède une branche de ce nom, sans quoi Git refuse plutôt que de choisir.
# Créer et suivre une branche distante existantegit switch --track origin/feature/api# Raccourci (si le nom n'existe qu'en remote) :git switch feature/apiSortie :
Switched to a new branch 'feature/api'branch 'feature/api' set up to track 'origin/feature/api'.Définir le tracking sur une branche existante
Section intitulée « Définir le tracking sur une branche existante »Cette variante sert quand la branche locale existe déjà, typiquement parce que
vous l'avez créée avant de savoir qu'elle vivait aussi sur le remote. git branch -u ne modifie aucun commit : il écrit deux lignes dans
.git/config et rien d'autre. Si la référence distante visée n'existe pas,
Git refuse avec fatal: the requested upstream branch ... does not exist
plutôt que de créer une configuration cassée.
git branch -u origin/feature/auth# ougit branch --set-upstream-to=origin/feature/authVoir toutes les relations de tracking
Section intitulée « Voir toutes les relations de tracking »git branch -vv est la commande de contrôle à retenir : elle affiche en une
fois, pour chaque branche locale, son dernier commit, son upstream entre
crochets et l'écart avec lui. Une branche sans crochets n'a pas
d'upstream ; c'est elle qui produira le message d'erreur au prochain
git pull.
git branch -vvSortie :
feature/auth a1b2c3d [origin/feature/auth: ahead 2] Ajouter JWT* main i7j8k9l [origin/main] Merge PR #42 fix/header e4f5g6h [origin/fix/header: behind 1] Corriger z-index- ahead 2 : vous avez 2 commits locaux non poussés
- behind 1 : le remote a 1 commit que vous n'avez pas
- Pas d'indication : synchronisé
Pousser une branche
Section intitulée « Pousser une branche »Premier push (créer la branche distante)
Section intitulée « Premier push (créer la branche distante) »git push -u origin feature/loginLe -u (ou --set-upstream) crée la branche sur le remote et
configure le tracking. Les push suivants n'ont besoin que de :
git pushPousser toutes les branches
Section intitulée « Pousser toutes les branches »Cette commande existe surtout pour un cas précis : migrer un dépôt d'un hébergeur vers un autre, où l'on veut effectivement tout transférer d'un coup. Dans le travail quotidien elle est rarement le bon geste, parce qu'elle n'exclut rien et ne demande pas confirmation.
git push --all originSupprimer une branche distante
Section intitulée « Supprimer une branche distante »Après le merge d'une PR, supprimez la branche distante pour garder un remote propre :
git push origin --delete feature/loginTo git@github.com:mon-orga/api-meteo.git - [deleted] feature/loginCette commande supprime la branche sur le serveur et la référence
origin/feature/login dans votre dépôt. Elle ne touche pas à votre branche
locale, qui existe toujours : c'est pourquoi la vérification doit se faire sur
les seules références distantes, avec git branch -r et non git branch -a.
git branch -r | grep feature/login# Aucun résultat = suppression réussie côté remoteN'oubliez pas de supprimer la branche locale aussi :
git branch -d feature/loginSi Git répond error: the branch 'feature/login' is not fully merged, c'est
que la branche porte des commits absents de la branche courante. Vérifiez avec
git log main..feature/login --oneline avant d'employer git branch -D, qui
supprime sans contrôle.
Synchroniser un fork
Section intitulée « Synchroniser un fork »Si vous travaillez sur un fork, vous avez généralement deux remotes :
# Ajouter le dépôt original comme remote "upstream"git remote add upstream https://github.com/original/repo.git
# Vérifier les remotesgit remote -vPour synchroniser votre fork :
git fetch upstreamgit switch maingit merge upstream/maingit push origin mainDépannage : problèmes courants
Section intitulée « Dépannage : problèmes courants »Presque toutes ces situations viennent d'un décalage entre ce que vous croyez
savoir du remote et ce que vos références locales contiennent réellement. Le
premier réflexe est donc git fetch --prune, qui rafraîchit les références et
supprime celles dont la branche n'existe plus côté serveur ; relisez ensuite
git branch -vv. Le message exact renvoyé par Git est votre meilleur point
d'entrée dans ce tableau, la première colonne reprend les formulations
littérales.
| Symptôme | Cause probable | Solution |
|---|---|---|
There is no tracking information for the current branch | Pas de tracking configuré | git branch -u origin/ma-branche |
! [rejected] (non-fast-forward) ou (fetch first) | Remote a divergé | git pull --rebase puis git push |
git branch -a liste une branche distante supprimée sur le serveur | Référence obsolète non nettoyée | git fetch --prune pour nettoyer |
fatal: the requested upstream branch ... does not exist | Upstream visé absent après suppression ou faute de frappe | git fetch --prune puis vérifier avec git branch -r |
ahead N, behind M | Désynchronisation locale/remote | git pull --rebase pour rattraper le retard, puis git push |
À retenir
Section intitulée « À retenir »origin/mainest une référence locale, pas la branche distante elle-mêmegit fetchmet à jour les références distantes sans toucher à vos branchesgit pull=git fetch+git merge(ou--rebase)git push -ucrée la branche distante et configure le trackinggit branch -vvmontre ahead/behind pour chaque branchegit push origin --deletesupprime une branche sur le remote