Aller au contenu principal

Git : les six commandes que tu n'as jamais comprises, et qui te bloquent en équipe

Rebase, reset, cherry-pick, reflog. Les mots qui te font transpirer en review. Voici la vérité simple derrière chacun, et pourquoi ils ne sont pas plus durs que add ou commit, juste mal expliqués.

Guides & tutoriels ·
Adel LATIBI
Adel LATIBI

Le Briefing Dev - les ressources et actus de la semaine, droit dans ta boîte chaque vendredi gratuitement.

En vous inscrivant, vous acceptez de recevoir notre newsletter. Désinscription possible à tout moment.

Beaucoup de développeurs utilisent Git tous les jours avec quatre commandes: git add, git commit, git push, git pull. Ça suffit au quotidien. Puis un jour, le tech lead demande "tu peux rebase ta branche sur main avant de merger ?". Là, c'est le trou noir. Direction Google, puis dix articles qui se contredisent.

C'est une maîtrise partielle de Git: quatre commandes sur la trentaine d'utiles, et les six qui débloqueraient le plus de situations restent dans l'angle mort. Quand un truc tourne mal, la solution de secours devient "je supprime ma branche et je repars de main". Parfois une demi-journée de travail passe à la trappe, et on se dit que c'est le prix à payer.

Ces commandes ne sont pas difficiles en soi. Ce qui manque, c'est un modèle mental clair. La plupart des tutoriels donnent des recettes ("tape ça, ça marche") sans la logique en dessous. Dès que la situation s'écarte un peu de la recette, plus rien ne tient.

Cet article donne la logique derrière six commandes Git qui font peur, dans un ordre qui construit la compréhension étape par étape. À la fin, tu n'auras pas tout couvert, mais tu auras le modèle mental pour apprendre le reste seul.

Le problème : on t'a appris Git comme une liste de recettes

La plupart des cours Git suivent ce schéma : voici les commandes de base, faites-les dans cet ordre, copiez le pense-bête. Ça marche pour les premières semaines. Ça craque dès qu'une situation imprévue arrive : un commit raté à modifier, deux branches qui ont divergé, un fichier qui revient de nulle part.

Le mot qui manque dans cet apprentissage, c'est "graphe". Git n'est pas un éditeur de texte avec un bouton sauvegarder. C'est un graphe de commits, chaque commit pointant vers son ou ses parents. Toutes les commandes que tu trouves obscures sont en réalité des manipulations sur ce graphe. Une fois que tu visualises le graphe, tout devient évident.

L'autre concept-clé manquant, c'est la distinction entre les "zones" de Git : le working directory (ton dossier de travail), l'index ou staging (ce qui sera dans le prochain commit), le HEAD (le dernier commit de ta branche locale), et le remote (le serveur, GitHub ou autre). Chaque commande déplace des choses entre ces zones.

Avec ces deux idées, le graphe et les zones, 80% du mystère de Git disparaît. Les commandes ne sont plus des incantations, ce sont des verbes qui agissent sur des objets bien définis.

Le principe : six commandes dans l'ordre où elles s'apprennent

1. git stash : poser ton boulot en cours sans commit

Le cas typique : tu es en train de bosser sur une fonctionnalité, ton code n'est pas prêt à être commit, et il faut que tu changes de branche pour une urgence. Tu ne peux pas changer de branche avec des modifications non sauvées, Git va râler.

git stash met de côté tes modifications en cours dans une pile. Tu peux maintenant changer de branche, traiter ton urgence, revenir, et faire git stash pop pour récupérer ton travail.

Trois commandes te suffisent. git stash pour ranger. git stash list pour voir ce qui est rangé. git stash pop pour récupérer le dernier. C'est la commande la plus simple de la liste, et elle te sauve plusieurs fois par semaine.

2. git reset : revenir en arrière, à trois niveaux différents

La commande qui fait paniquer parce que ses options sont confuses. En vrai, c'est simple si tu te rappelles des trois zones (working directory, index, HEAD).

  • git reset --soft HEAD~1 : annule le dernier commit, mais garde tes changements en staging. Utile quand tu as mal nommé un commit ou oublié un fichier.
  • git reset --mixed HEAD~1 (ou simplement git reset HEAD~1) : annule le commit et sort tes changements du staging, ils restent dans tes fichiers.
  • git reset --hard HEAD~1 : annule le commit ET supprime les changements de tes fichiers. Tu perds ton travail. À utiliser seulement quand tu es absolument sûr.

Modèle mental : soft annule le commit, mixed annule le commit et le staging, hard annule tout. La dangerosité augmente avec la longueur du mot. Mémorise cette progression et tu ne fais plus jamais d'erreur.

3. git rebase : réécrire l'historique de ta branche

La commande qui terrorise les juniors et qui est en réalité super utile. Le rebase prend tes commits et les "rejoue" par-dessus une autre branche, comme si tu avais fait ton travail à partir de cette branche dès le départ.

Cas typique : tu as une branche feature/login partie de main il y a trois jours. Pendant ce temps, main a avancé. Tu veux que ta branche soit basée sur la version actuelle de main pour éviter les conflits au merge.

git checkout feature/login
git fetch origin
git rebase origin/main

Git va replacer tes commits par-dessus la version actuelle de main. S'il y a un conflit, il s'arrête, tu résous, tu fais git add sur les fichiers résolus, puis git rebase --continue.

Règle absolue : tu ne rebase JAMAIS une branche partagée avec d'autres. Le rebase réécrit l'historique, et si quelqu'un travaillait sur l'ancienne version, tu casses tout. Sur ta branche perso avant un merge dans main, c'est parfait. Sur main, jamais.

4. git cherry-pick : récupérer un commit précis sans tout merger

Tu as fait un commit important sur une branche, et tu veux ce commit aussi sur une autre branche, sans merger toute la branche d'origine. C'est exactement le cas pour cherry-pick.

git checkout main
git cherry-pick <hash-du-commit>

Tu récupères le hash du commit avec git log (les 7 premiers caractères suffisent). Tu le cherry-pick sur la branche cible, et Git applique exactement ce commit à cet endroit.

Utilisations courantes : appliquer un hotfix sur plusieurs versions, récupérer une partie d'une branche que tu ne veux pas fusionner complètement. À utiliser avec parcimonie, parce que tu duplique l'historique du commit (le même changement existe à deux endroits avec deux hashs différents).

5. git reflog : ton filet de sécurité absolu

La commande la plus importante de cette liste, et la moins connue. Git garde une trace de tous les déplacements de HEAD pendant 90 jours, même quand tu fais des opérations destructrices. Cette trace, c'est le reflog.

git reflog

Tu vois une liste de toutes les opérations récentes avec leur hash. Tu as fait un reset --hard et tu as perdu des commits ? Tu retrouves leur hash dans le reflog, et tu fais git reset --hard <hash> pour revenir à cet état. Tes commits sont récupérés.

Tant que tu connais le reflog, tu ne peux quasiment rien perdre dans Git. C'est cette commande qui devrait te donner le courage d'expérimenter avec les autres : tu sais que tu peux toujours revenir en arrière.

6. git rebase -i : réécrire proprement ses commits avant un merge

Le rebase interactif. Sur une feature branch, tu as fait dix commits : "wip", "fix typo", "ajout bouton", "encore un fix", "ah ça marche". Avant de pousser pour review, tu veux nettoyer cet historique. Le rebase interactif fait ça.

git rebase -i HEAD~5

Git ouvre ton éditeur avec la liste des 5 derniers commits. Pour chacun, tu peux : pick (garder), squash (fusionner avec le précédent), reword (changer le message), drop (supprimer). Tu sauves, Git réécrit ta branche.

Résultat : au lieu de dix commits sales, tu présentes deux commits propres en review. Le tech lead voit ta vraie intention, pas le brouillon. C'est un signe de maturité dev qui se remarque très vite.

Exemple : un workflow propre de la branche au merge

Voici comment ces commandes s'enchaînent dans un workflow réel, sur une branche de fonctionnalité.

# Je pars de main a jour
git checkout main
git pull

# Je cree ma branche
git checkout -b feature/checkout-stripe

# Je code, je commit plusieurs fois
git add .
git commit -m "wip stripe integration"
# ... 4 autres commits brouillons ...

# Avant de pousser, je nettoie mon historique
git rebase -i HEAD~5
# Je squashe les 5 commits en 2 propres

# Pendant ce temps, main a avance, je me mets a jour
git fetch origin
git rebase origin/main
# Si conflit : je resous, git add, git rebase --continue

# Je pousse (avec --force-with-lease car j'ai reecrit l'historique)
git push --force-with-lease origin feature/checkout-stripe

# J'ouvre la PR sur GitHub, elle est propre, le tech lead est content

Ce workflow combine rebase interactif (nettoyage) et rebase classique (mise à jour). À la fin, ta branche a un historique propre et linéaire, qui se mergue sans bavure dans main.

Important : --force-with-lease au lieu de --force. Cette variante refuse de pousser si quelqu'un d'autre a poussé sur ta branche entre-temps, ce qui te protège d'écraser le travail d'un collègue.

Pièges classiques à éviter

Faire git push --force sur une branche partagée

Tu as réécrit l'historique de ta branche locale, tu pousses avec --force. Tu écrases sans le savoir trois commits qu'un collègue avait poussés. Il a perdu son travail. La journée est gâchée.

Toujours --force-with-lease, jamais --force. La différence prend trois caractères en plus et te sauve des catastrophes.

Rebase main sur ta branche au lieu de l'inverse

Tu fais git checkout main puis git rebase feature/login en pensant que tu mets à jour ta branche. En réalité, tu réécris l'historique de main. Catastrophe en équipe.

La règle simple : tu te places toujours sur ta branche de feature, et tu rebase sur main. git checkout feature puis git rebase main. Tu rebase ta branche sur autre chose, pas l'inverse.

Paniquer après un git reset --hard

Tu as fait git reset --hard HEAD~3, tu réalises que tu viens de perdre tes trois derniers commits. Tu paniques, tu googles, tu te dis que c'est foutu.

Le reflog est ton ami. git reflog, tu retrouves le hash de ton état précédent, git reset --hard <hash>, tu es de retour. Ce n'est jamais foutu tant que tu n'as pas attendu 90 jours.

Mal nommer ses commits

"fix", "wip", "update", "encore un truc". Six mois plus tard, tu cherches qui a introduit un bug, l'historique ne te dit rien.

Un bon message de commit commence par un verbe à l'impératif (add, fix, refactor, remove), décrit le quoi et le pourquoi, tient en une ligne courte (50 caractères ou moins pour le titre). Si tu utilises le rebase interactif, tu nettoies les "wip" avant de pousser. C'est ce qui distingue un historique professionnel d'un historique brouillon.

Ignorer les conflits au lieu de les comprendre

Tu as un conflit lors d'un merge ou d'un rebase, tu paniques, tu acceptes "toutes les leurs" ou "toutes les miennes" sans regarder. Tu pousses du code cassé.

Un conflit n'est pas une erreur, c'est une question que Git te pose : "deux versions différentes existent pour ces lignes, laquelle veux-tu ?". Tu lis le fichier, tu choisis ligne par ligne, tu testes, tu commits. Les conflits sont normaux, c'est ta capacité à les résoudre qui te distingue.

Croire qu'il faut tout savoir avant d'utiliser

Tu attends de "vraiment comprendre Git" pour oser utiliser rebase. Tu ne comprends pas tant que tu n'utilises pas. Tu utilises seulement quand tu comprends. Tu es coincé.

Tu crées une branche jetable sur ton projet perso, tu fais des commits bidons, et tu joues. reset, rebase, cherry-pick, tu casses tout, tu récupères avec le reflog. Une heure de jeu vaut dix heures de tutoriel.

Pour aller plus loin

Maîtriser Git change ton positionnement dans l'équipe. Un junior qui sait rebase proprement passe pour un dev sérieux, parce que la propreté de son historique de commits se voit en review. L'article sur les apprendre par la pratique plutôt que par les tutoriels s'applique parfaitement ici : tu ne maîtrises Git qu'en l'utilisant sur de vrais projets.

Côté formation, la formation Git et GitHub : versionner et collaborer couvre ces commandes en profondeur avec des exercices reproductibles. La formation CI/CD avec GitHub Actions prend le relais pour la partie automatisation autour de Git.

Questions fréquentes

Merge ou rebase, lequel utiliser ?

Les deux ont leur place. Rebase pour nettoyer ta propre branche avant de la pousser ou avant de la merger dans main (historique linéaire, propre). Merge pour intégrer une PR validée dans main (préserve le contexte de la PR). La règle d'or : rebase tant que tu es seul sur ta branche, merge quand tu intègres dans une branche partagée. Beaucoup d'équipes utilisent la stratégie "squash and merge" sur GitHub, qui combine les deux : tu rebases en local, puis GitHub squashe ta PR en un seul commit lors du merge.

Comment annuler un commit déjà poussé sur le serveur ?

Si tu es seul sur la branche, tu peux faire git reset puis git push --force-with-lease. Si la branche est partagée ou si c'est main, tu n'annules jamais avec un reset, tu utilises git revert. revert crée un nouveau commit qui inverse les changements du commit fautif. L'historique reste intact, ton équipe n'a rien à faire de spécial pour récupérer la situation.

Pourquoi mon git pull crée parfois un commit de merge ?

Quand tu fais git pull et que ta branche locale a divergé de la branche distante (toi tu as commit, le serveur aussi), Git fait un merge par défaut, ce qui crée un commit de merge polluant. Pour éviter ça, configure git pull en rebase par défaut : git config --global pull.rebase true. Ton pull va d'abord récupérer les nouveaux commits puis rebase les tiens par-dessus. Historique propre, sans merge parasites.

Faut-il utiliser une interface graphique Git ou la ligne de commande ?

Une interface graphique (GitKraken, Sourcetree, l'onglet Git de VS Code) est utile pour visualiser le graphe et faire des opérations courantes. La ligne de commande est nécessaire pour les commandes avancées et pour comprendre ce qui se passe vraiment. Beaucoup de devs experts utilisent les deux : interface pour voir, terminal pour agir. Tu peux commencer par l'interface si elle te rassure, mais tu dois finir par maîtriser la ligne de commande pour ne pas être dépendant d'un outil.

C'est quoi un commit "atomique" et pourquoi c'est important ?

Un commit atomique fait une seule chose, et la fait complètement. "Fix bug pagination" est atomique. "Fix pagination et refactor service utilisateur et ajout endpoint API" ne l'est pas. L'intérêt : tu peux revert un commit atomique sans casser autre chose, tu peux le cherry-pick utilement, et tu lis ton historique sans confusion. C'est une discipline qui demande de l'entraînement, et qui distingue très vite les devs sérieux.

Comment gérer un fichier que je ne veux pas commit, comme un mot de passe en clair ?

Tu l'ajoutes au .gitignore avant le premier commit. Si tu as déjà commité le fichier, le supprimer du commit suivant ne suffit pas, il reste dans l'historique et donc dans le repo. Tu dois utiliser git filter-repo (ou l'ancienne git filter-branch) pour nettoyer l'historique complètement, puis force-pusher (avec coordination de l'équipe). Et tu changes immédiatement les secrets exposés, parce qu'on doit considérer qu'ils sont compromis dès qu'ils ont été poussés.

Vous êtes expert ?

Partagez votre expertise sur notre blog

Tutoriel, retour d'expérience, analyse - publiez un article invité et gagnez en visibilité.

Écrire pour nous