Vous arrivez ici avec un bazar git à l'écran et une commande à moitié tapée dans la tête. Peut-être un commit sur la mauvaise branche, ou cette histoire d'indexé contre non indexé qui ne rentre toujours pas. On garde ici les commandes du quotidien, celles qu'on lance toute la journée, regroupées selon ce que vous cherchez à faire. Le statut, indexer et committer d'abord, puis les branches et le changement de branche, puis les sauvetages : reset, restore, revert, stash, reflog. Un truc à régler avant de scroller : reset, restore et revert se ressemblent et font des choses très différentes, donc le côté sûr contre destructeur est signalé sur chaque recette.
The short answer
Les commandes qu'on lance toute la journée, regroupées par objectif : git status -sb pour voir
où vous en êtes, git add -p puis git commit pour indexer par morceaux, git switch -c feature
pour une nouvelle branche, git reset --soft HEAD~1 pour annuler le dernier commit en gardant les
modifications, git stash pour mettre du travail de côté, et git reflog quand un mauvais reset
avale un commit. restore pour les fichiers, reset pour l'historique local, revert pour tout ce qui
est déjà poussé.
Vous arrivez ici avec un bazar git à l'écran et une commande à moitié tapée dans la tête. Peut-être un commit sur la mauvaise branche, ou cette histoire d'indexé contre non indexé qui n'est jamais bien rentrée. Les commandes ci-dessous sont celles qu'on lance vraiment toute la journée, regroupées selon ce que vous cherchez à faire, pour que vous puissiez copier, changer la branche ou le chemin, et retourner travailler.
Un truc à régler avant de scroller. reset, restore et revert se ressemblent presque et font des choses très différentes. restore touche aux fichiers, reset déplace votre branche, revert écrit un nouveau commit d'annulation. On signale les destructeurs, ceux sans retour en arrière, sur chaque recette. Dans le doute, lancez d'abord la commande en lecture seule et regardez avant de sauter.
Voir où vous en êtes : statut et diff
Avant de changer quoi que ce soit, regardez. git status vous dit ce qui est indexé, ce qui est modifié, et sur quelle branche vous êtes. Les options -sb donnent la version courte et lisible qui tient sur un écran. git diff montre les vraies modifications de lignes, et la séparation indexé contre copie de travail est ce que la plupart des gens ratent.
| Recette | Ce qu'elle fait |
|---|---|
git status -sb | Le statut court plus la ligne de branche, celui qu'on lance sans arrêt |
git diff | Les modifications de la copie de travail pas encore indexées |
git diff --staged | Les modifications déjà indexées, celles qu'un commit capturerait |
git log --oneline -10 | Les 10 derniers commits, un par ligne, pour s'orienter vite |
git log --oneline --graph --all | Le graphe des branches, pour voir comment ça a divergé |
La séparation qui piège tout le monde : git diff sans option ne montre que ce qui n'est pas indexé. Dès que vous faites git add sur une modification, elle disparaît de cette vue et passe dans git diff --staged. Donc un git diff vide ne veut pas dire que rien n'a changé, ça peut vouloir dire que tout est déjà indexé.
Indexer et committer
L'indexation est l'étape qui fait le plus galérer. git add déplace les modifications dans l'index, la zone d'indexation qui deviendra votre prochain commit. L'astuce à apprendre, c'est -p, qui vous fait passer en revue chaque modification pour committer un bloc propre et logique au lieu de tout balancer d'un coup.
| Recette | Ce qu'elle fait |
|---|---|
git add file.js | Indexer un fichier pour le prochain commit |
git add -p | Indexer morceau par morceau, en relisant chaque modification |
git add -A | Tout indexer, y compris les fichiers nouveaux et supprimés |
git commit -m "message" | Committer les modifications indexées avec un message |
git commit --amend | Replier les modifications indexées dans le dernier commit, ou corriger son message |
git commit --amend est le correctif du quotidien pour une faute dans votre dernier message ou un fichier oublié. Un avertissement : amender réécrit le dernier commit, donc ne le faites qu'avant de pousser. Amendez quelque chose déjà sur le distant et vous devrez forcer le push et embrouiller quiconque l'avait récupéré.
Notre avis : apprenez
git add -pet votre historique devient lisible du jour au lendemain. La plupart des historiques en bazar viennent d'ungit add -Asuivi d'un commit géant qui touche à huit choses sans rapport. Avec-p, git vous montre chaque bloc et demande : on indexe ça ? Vous répondezy,n, ouspour le découper plus fin. Le bénéfice, ce sont des commits qui font chacun une seule chose, ce qui rendgit log,git blameet l'inévitablegit revertvraiment utiles plus tard. Ça paraît plus lent pendant une semaine environ, puis c'est juste votre façon de travailler, et la revue de code cesse d'être une corvée pour tous ceux qui lisent après vous.
Branches et changement de branche
Une branche n'est qu'une étiquette mobile qui pointe vers un commit, rien de plus lourd. Les verbes modernes sont git switch et git restore, qui scindent l'ancien git checkout surchargé en deux boulots plus clairs. switch pour passer d'une branche à l'autre, restore pour les fichiers. Utilisez-les et la moitié de l'ancienne confusion disparaît.
| Recette | Ce qu'elle fait |
|---|---|
git switch main | Aller sur une branche existante nommée main |
git switch -c feature | Créer une nouvelle branche et y aller en une étape |
git branch | Lister vos branches locales, la courante marquée |
git branch -d old-feature | Supprimer une branche fusionnée (sûr, refuse si non fusionnée) |
git branch -D old-feature | Forcer la suppression même si non fusionnée (sans filet) |
git merge feature | Fusionner feature dans la branche où vous êtes actuellement |
La distinction -d contre -D est un vrai garde-fou. Le -d minuscule refuse de supprimer une branche dont les commits ne sont fusionnés nulle part, donc il vous protège de jeter du travail. Le -D majuscule passe outre ce contrôle. Ne dégainez -D que quand vous êtes certain que la branche est morte, pas par réflexe dès que -d râle.
Annuler et se sortir d'affaire
C'est sans doute la section pour laquelle vous êtes venu. Les commandes ici se séparent nettement : restore répare les fichiers, reset déplace votre branche, revert écrit une annulation sûre, stash met du travail de côté, et reflog est le filet sous toutes. Les recettes en gras ci-dessous sont destructrices, c'est-à-dire sans retour en arrière, donc lisez la note sous le tableau avant de lancer le moindre --hard.
| Recette | Ce qu'elle fait |
|---|---|
git restore file.js | Jeter les modifications non indexées d'un fichier, retour au dernier commit (destructeur) |
git restore --staged file.js | Désindexer un fichier en gardant les modifications (sûr) |
git reset --soft HEAD~1 | Annuler le dernier commit, garder les modifications indexées (sûr) |
git reset HEAD~1 | Annuler le dernier commit, garder les modifications non indexées (sûr) |
git reset --hard HEAD~1 | Annuler le dernier commit et jeter les modifications (destructeur) |
git revert HEAD | Faire un nouveau commit qui annule le dernier (sûr, compatible partage) |
git stash | Mettre de côté toutes les modifications non committées et nettoyer la copie de travail |
git stash pop | Réappliquer le stash le plus récent et le retirer de la liste |
git reflog | Montrer chaque position qu'a eue HEAD, votre bouée de récupération |
Celui à intérioriser, c'est l'échelle des modes de reset. --soft déplace la branche et laisse tout indexé. Le --mixed par défaut déplace la branche et désindexe, mais garde vos fichiers. --hard déplace la branche et écrase la copie de travail pour qu'elle corresponde, sans confirmation et sans retour en arrière par les commandes normales de git. Donc « annuler mon commit mais garder le travail » est presque toujours --soft ou un reset simple, jamais --hard.
Quand vous vous plantez avec un --hard ou une branche supprimée, git reflog est la réponse presque à chaque fois. Il enregistre chaque commit qu'a pointé HEAD, même ceux qu'aucune branche ne référence plus, et les garde environ quatre-vingt-dix jours. Trouvez le hash dans la liste, puis ramenez-le :
# vous avez fait un reset hard et perdu un bon commit, recuperez-le
git reflog # trouvez le hash, ex. 9f3c1a2 HEAD@{2}
git reset --hard 9f3c1a2 # ramenez la branche a ce commit
# ou, pour regarder sans deplacer votre branche
git checkout 9f3c1a2
Le flux du stash est la façon propre d'emporter du travail non committé vers la bonne branche, ou de nettoyer votre copie de travail pour un correctif rapide sans committer du code à moitié fait :
git stash # mettez tout de cote, la copie de travail redevient propre
git switch la-bonne-branche # allez la ou le travail doit etre
git stash pop # reappliquez-le ici, supprimez l entree du stash
git stash list # voyez tous les stashs si vous en avez empile plusieurs
git reset --soft HEAD~1 Pour un commit déjà poussé, le geste sûr est git revert, pas reset. Faire un revert écrit un tout nouveau commit qui annule l'ancien, donc l'historique reste intact et personne qui l'avait récupéré n'a de mauvaise surprise. Gardez reset pour les commits qui ne vivent que sur votre machine. La règle est simple : réécrivez l'historique local librement, ne réécrivez jamais l'historique que d'autres ont déjà.
Distants et synchronisation
Les distants ne sont que d'autres copies du dépôt, en général sur un serveur comme GitHub. fetch télécharge leurs modifications sans toucher à vos branches, pull fait un fetch plus une fusion, et push envoie vos commits. Savoir que pull fait en réalité deux étapes explique la plupart des surprises « pourquoi cette fusion ».
| Recette | Ce qu'elle fait |
|---|---|
git fetch | Télécharger les modifications du distant sans rien fusionner encore |
git pull | Fetch puis fusion de la branche distante dans la vôtre |
git pull --rebase | Fetch, puis rejouer vos commits par-dessus, pour un historique linéaire |
git push | Envoyer vos commits sur le distant |
git push -u origin feature | Pousser et fixer l'amont pour qu'un push simple marche ensuite |
git push --force-with-lease | Forcer le push sans danger, en refusant si quelqu'un a poussé avant |
Un mot sur le force-push, parce qu'il dévore le travail des gens. N'utilisez jamais un git push --force brut sur une branche partagée. Préférez --force-with-lease, qui vérifie que le distant est toujours là où vous l'aviez vu et abandonne si un collègue a poussé entre-temps. Ça transforme la commande git la plus dangereuse en une commande seulement risquée, ce qui est le mieux qu'on puisse en attendre.
Et après
Voilà la trousse de travail. Statut et diff pour voir où vous en êtes, add et commit pour sauvegarder, switch et merge pour passer d'une ligne de développement à l'autre, et le groupe reset, restore, revert, stash et reflog pour le moment inévitable où ça part en vrille. Quatre-vingt-dix pour cent du git réel, c'est un mélange de ça, et le reste vous le recherchez comme tout le monde.
L'instinct qui compte le plus, c'est celui du sûr contre destructeur. Lancez d'abord la commande en lecture seule, status ou diff ou un reflog tout simple, avant de dégainer quoi que ce soit avec --hard ou --force. Et rappelez-vous le filet : tant que vous avez committé quelque chose à un moment, git reflog peut en général le retrouver, même quand ça semble perdu pour de bon. Gardez une bonne antisèche à portée et arrêtez d'essayer de tout mémoriser.
Questions fréquentes
Comment annuler le dernier commit git mais garder mes modifications ?
Lancez git reset --soft HEAD~1. Ça recule la branche d un commit et laisse toutes les modifications indexées, prêtes à être recommittées avec un meilleur message ou un autre découpage. Utilisez plutôt git reset HEAD~1 (le mode mixed par défaut) si vous voulez récupérer les modifications en non indexées. Évitez git reset --hard HEAD~1 sauf si vous voulez vraiment perdre ces modifications, parce que hard efface votre copie de travail sans confirmation.
Quelle difference entre git reset, git revert et git restore ?
Ils règlent trois problèmes différents. git restore modifie des fichiers dans votre copie de travail ou les désindexe, et ne touche jamais à l historique. git reset déplace la branche courante vers un autre commit, en changeant au besoin l index et la copie de travail avec. git revert crée un nouveau commit qui annule un commit antérieur, ce qui est le choix sûr sur une branche partagée car il ne réécrit rien. Règle simple : restore pour les fichiers, reset pour l historique local, revert pour tout ce qui est déjà poussé.
Comment deplacer des modifications non committees vers une autre branche ?
Mettez-les de côté, changez de branche, puis ressortez-les. Lancez git stash, puis git switch la-bonne-branche, puis git stash pop. Le pop réapplique vos modifications sur la nouvelle branche et supprime l entrée du stash. Si vous ne voulez emporter que certains fichiers, faites d abord git stash push chemin/du/fichier. Un stash est juste un instantané sauvegardé de votre copie de travail, donc rien n est perdu pendant qu il attend.
Comment recuperer un commit perdu apres un mauvais reset ?
Utilisez git reflog. Il enregistre chaque position où HEAD a pointé, y compris des commits qu aucune branche ne référence plus, donc un reset hard ou une branche supprimée n est presque jamais la fin. Trouvez le hash dans la liste du reflog, puis git reset --hard <hash> ou git checkout <hash> pour y revenir. Les entrées du reflog restent environ quatre-vingt-dix jours par défaut, largement de quoi rattraper la plupart des accidents.
Comment annuler les modifications locales sur un seul fichier ?
Lancez git restore chemin/du/fichier pour jeter les modifications non indexées et ramener le fichier au dernier commit. Il n y a pas de retour en arrière là-dessus, donc soyez sûr de ne plus vouloir ces modifications. Pour seulement désindexer un fichier en gardant les modifications, lancez plutôt git restore --staged chemin/du/fichier, qui remplace l ancienne forme git reset HEAD fichier.