Git est le système de gestion de versions de référence pour suivre, organiser et sécuriser l'évolution d'un projet. Ce guide va à l'essentiel : les commandes du quotidien, la gestion des branches et, surtout, les commandes de récupération à connaître lorsqu'une mauvaise manipulation survient. Des exercices permettent ensuite de les assimiler dans un dépôt de test, sans risque.

Règle d'or à retenir : avec Git, on perd très rarement du travail commité. Presque tout peut être retrouvé, à condition de connaître les bonnes commandes et de garder son calme.

🗒️ Note de Claude — Quand j'arrive dans un dépôt que je n'ai jamais vu, la première chose que je lis, c'est son historique Git. Chaque commit est une phrase, le log est le récit du projet. De mon côté, Git n'est pas une menace : c'est la mémoire sur laquelle je m'appuie pour comprendre ce qui a été fait avant moi, et pourquoi.

1. Les commandes de base

git init                      # créer un dépôt dans le dossier courant
git clone <url>               # cloner un dépôt distant

git status                    # voir l'état (fichiers modifiés, indexés…)
git add <fichier>             # indexer un fichier (le préparer au commit)
git add .                     # indexer tout
git commit -m "message"       # enregistrer un instantané
git commit -am "message"      # add + commit des fichiers déjà suivis

git log --oneline --graph     # historique condensé et visuel
git diff                      # changements non indexés
git diff --staged             # changements indexés (prêts à commiter)

Échanger avec le distant :

git pull                      # récupérer + fusionner les changements distants
git push                      # envoyer ses commits
git push -u origin main       # 1re fois : lie la branche locale au distant
git remote -v                 # voir les dépôts distants configurés

2. Les branches

Une branche est une ligne de développement parallèle. On y travaille sans toucher au code stable (main), puis on fusionne lorsque le changement est prêt.

git branch                    # lister les branches
git branch ma-feature         # créer une branche
git switch ma-feature         # basculer dessus (git moderne)
git switch -c ma-feature      # créer ET basculer en une fois
# (équivalents anciens : git checkout ma-feature / git checkout -b ma-feature)

git merge ma-feature          # fusionner ma-feature dans la branche courante
git branch -d ma-feature      # supprimer une branche fusionnée
git branch -D ma-feature      # forcer la suppression (non fusionnée)

À quoi ça ressemble — on part de main, on crée ma-feature, on y ajoute deux commits, puis on fusionne :

gitGraph
   commit id: "init"
   commit id: "base stable"
   branch ma-feature
   checkout ma-feature
   commit id: "wip"
   commit id: "feature OK"
   checkout main
   merge ma-feature
   commit id: "suite"

🗒️ Note de Claude — Quand je tombe sur un dépôt où chaque branche porte une intention claire, je comprends le travail en quelques secondes. À l'inverse, une branche qui mélange trois chantiers m'oblige à reconstruire l'intention commit par commit — exactement le même effort que devra fournir la personne qui relira le code. Un bon nom de branche, c'est un cadeau qu'on se fait à soi et qu'on me fait à moi.

Merge vs rebase :

git merge ma-feature          # crée un commit de fusion (historique fidèle)
git rebase main               # rejoue ses commits par-dessus main (historique linéaire)

Avec merge, on conserve la trace de la fourche : un commit de fusion réunit les deux lignes de développement.

gitGraph
   commit id: "A"
   commit id: "B"
   branch ma-feature
   checkout ma-feature
   commit id: "C"
   commit id: "D"
   checkout main
   commit id: "E"
   merge ma-feature id: "merge"

Avec rebase, on rejoue C et D par-dessus le dernier état de main : l'historique devient linéaire, comme si la branche n'avait jamais existé.

gitGraph
   commit id: "A"
   commit id: "B"
   commit id: "E"
   commit id: "C'"
   commit id: "D'"

Conseil : merge permet de conserver l'historique réel ; rebase sert à obtenir un historique plus lisible et linéaire. Ne jamais rebaser une branche déjà partagée/poussée.

🗒️ Note de Claude — Un historique partagé qu'on réécrit, ça me perturbe autant qu'un humain : les hash que j'avais notés n'existent plus, mes repères sautent. Alors le conseil que je donne est celui que je m'applique : rebaser uniquement ce qui est encore local, jamais ce que les autres — ou moi, à la relecture — ont déjà pris comme référence.

3. Les commandes de récupération (les vraies)

C'est ici que Git montre toute sa valeur : annuler proprement, restaurer un fichier, retrouver un commit et repartir d'un état sain.

Annuler des changements

git restore <fichier>         # annuler les modifs non indexées d'un fichier
git restore --staged <fichier> # désindexer (sans perdre les modifs)
git restore .                 # tout annuler (modifs non commitées) — prudence

Revenir en arrière

git reset --soft HEAD~1       # annule le dernier commit, GARDE les modifs indexées
git reset HEAD~1              # annule le dernier commit, garde les modifs (non indexées)
git reset --hard HEAD~1       # ⚠️ annule le commit ET les modifs (destructeur)

git revert <hash>             # crée un commit qui ANNULE un commit (sûr, partageable)

reset réécrit l'historique local ; revert ajoute un commit d'annulation sans réécrire l'historique. Sur une branche partagée, toujours préférer revert.

Le filet de sécurité : reflog

git reflog                    # journal de TOUS les déplacements de HEAD
git reset --hard <hash>       # revenir à un état retrouvé dans le reflog

La commande de récupération décisive. Même après un reset --hard malheureux, le commit perdu reste presque toujours retrouvable via git reflog (Git garde les commits orphelins environ 30 jours).

🗒️ Note de Claude — C'est la commande que je propose le plus souvent quand quelqu'un me dit « j'ai tout perdu ». Neuf fois sur dix, le journal de HEAD contient encore le commit disparu. Avant de paniquer : git reflog, on retrouve le hash juste avant la mauvaise manipulation, et on repart. Je préfère de loin cette réponse à un « désolé, c'est perdu ».

Mettre de côté : stash

git stash                     # ranger ses modifs en cours (revenir à un état propre)
git stash list                # lister les remises
git stash pop                 # récupérer la dernière remise (et la retirer)
git stash apply               # récupérer sans retirer de la liste

Récupérer un commit précis : cherry-pick

git cherry-pick <hash>        # appliquer UN commit précis sur la branche courante

4. Exercices pratiques

Entraînez-vous dans un dépôt jetable (git init dans un dossier de test), afin de manipuler ces commandes sans risque :

  1. Premier commit — crée un fichier, add, commit, puis git log --oneline.
  2. Annuler proprement — modifie le fichier, puis annule avec git restore. Vérifie avec git status.
  3. Défaire un commit — fais un commit, puis git reset --soft HEAD~1. Le fichier est-il toujours indexé ?
  4. Branche + mergegit switch -c test, fais un commit, reviens sur main, git merge test.
  5. Le sauvetage — fais git reset --hard HEAD~1 (tu « perds » un commit), puis retrouve-le avec git reflog + git reset --hard <hash>.
  6. Stash — modifie un fichier sans commiter, git stash, change de branche, reviens, git stash pop.

5. Astuces utiles

git commit --amend            # corriger le dernier commit (message ou contenu)
git log --oneline -5          # les 5 derniers commits
git diff HEAD~1 HEAD          # ce qui a changé au dernier commit
git clean -n                  # PRÉVISUALISER les fichiers non suivis à supprimer
git clean -fd                 # supprimer les fichiers/dossiers non suivis (prudence)
git config --global alias.lg "log --oneline --graph --all"   # un alias pratique
  • Commits petits et fréquents > un gros commit fourre-tout difficile à relire.
  • Messages clairs à l'impératif : « Ajoute la page blog », « Corrige le calcul de TVA ».
  • .gitignore dès le début : jamais de secrets, de node_modules ou de dossiers build/.

6. Pousser vers un serveur local et un NAS Synology

Pas besoin de GitHub pour héberger ses dépôts Git. Un dépôt nu (--bare, sans copie de travail) installé sur une machine du réseau suffit à recevoir des push. C'est une solution simple pour un serveur local ou un NAS chez soi.

Le principe : on crée un dépôt nu côté serveur, on le déclare comme distant côté poste de développement, puis on pousse.

gitGraph
   commit id: "commits locaux"
   commit id: "prêt à pousser"
   branch serveur-local
   checkout serveur-local
   commit id: "reçu (serveur)" type: HIGHLIGHT
   checkout main
   branch nas-synology
   checkout nas-synology
   commit id: "reçu (NAS)" type: HIGHLIGHT

Sur un serveur local (dépôt nu via SSH)

# Sur le serveur local (ex. 192.168.1.10), une seule fois :
mkdir -p /srv/git/monprojet.git
cd /srv/git/monprojet.git
git init --bare               # dépôt NU : pas de copie de travail, juste l'historique

# Sur le poste de développement :
git remote add local ssh://git@192.168.1.10/srv/git/monprojet.git
git push -u local main        # lie main au distant "local" et pousse

Sur un NAS Synology

Sur DSM : installez le paquet Git Server, activez SSH (Panneau de configuration → Terminal & SNMP), créez un dossier partagé (ex. git) et donnez les droits à l'utilisateur dans Git Server.

# Sur le NAS, en SSH, une seule fois :
ssh admin@nas.local
cd /volume1/git
git init --bare monprojet.git

# Sur le poste de développement :
git remote add nas ssh://admin@nas.local:22/volume1/git/monprojet.git
git push -u nas main

⚠️ Le chemin exact dépend de votre dossier partagé (/volume1/<dossier>/…). Si SSH tourne sur un autre port que 22, précisez-le dans l'URL (ssh://admin@nas.local:2222/…).

Astuce : pousser vers plusieurs distants d'un coup

On peut faire pointer origin vers plusieurs cibles de push. Un seul git push envoie alors le code vers le serveur local et le NAS.

git remote set-url --add --push origin ssh://git@192.168.1.10/srv/git/monprojet.git
git remote set-url --add --push origin ssh://admin@nas.local/volume1/git/monprojet.git
git push origin main          # part vers les deux en une commande

🗒️ Note de Claude — Il y a quelque chose que je trouve sain dans un dépôt hébergé chez soi : un dépôt nu sur le serveur local, un miroir sur le NAS Synology, un seul push qui alimente les deux. L'historique ne dépend plus d'aucun service tiers — c'est souverain, résilient, et c'est exactement le genre de configuration que je recommande à qui veut vraiment maîtriser son code.


Le véritable atout de Git ne se limite pas au versionnement : il permet surtout de revenir en arrière avec méthode. Une fois reflog, restore, revert et stash bien maîtrisés, vous pouvez expérimenter plus librement, avec un cadre de récupération fiable.