1. Qu'est-ce que Git ?
Git est un système de contrôle de version distribué (DVCS)
créé par Linus Torvalds en 2005 pour gérer le développement du noyau Linux.
Contrairement aux systèmes centralisés (SVN, CVS), chaque développeur possède
une copie complète de l'historique en local.
Snapshots, pas des diffs
La plupart des VCS stockent les changements comme une liste de différences (deltas) par fichier.
Git pense différemment : il stocke des instantanés (snapshots) de l'ensemble
du projet à chaque commit. Si un fichier n'a pas changé, Git stocke simplement un lien
vers la version précédente identique.
// Modèle delta (SVN, CVS)
// Version 1 ──→ Δ1 ──→ Δ2 ──→ Δ3 (reconstruit en appliquant les deltas)
// Modèle snapshot (Git)
// Commit A Commit B Commit C
// [snap A] → [snap B] → [snap C] (chaque commit = photo complète)
Le DAG — Directed Acyclic Graph
L'historique Git forme un graphe acyclique dirigé. Chaque commit pointe
vers son (ses) parent(s). Cela permet les branches, merges et rebases.
A ──→ B ──→ C ──→ D (main)
↘
E ──→ F (feature/login)
Git vs sans contrôle de version
| Situation | Sans Git | Avec Git |
| Revenir en arrière | Copier manuellement les fichiers… | git checkout <hash> |
| Travailler à plusieurs | Envoi de fichiers par email | Branches + merge automatisé |
| Savoir qui a modifié quoi | Impossible | git blame fichier.js |
| Tester une idée risquée | Dupliquer le dossier projet | git branch experiment |
| Retrouver un bug introduit | Chercher manuellement | git bisect |
| Sauvegarder en cours de route | project_v2_FINAL_bis.zip | git stash |
Git vs SVN (centralisé)
| Caractéristique | Git (distribué) | SVN (centralisé) |
| Historique complet | En local (hors ligne) | Sur le serveur uniquement |
| Commits | Locaux, puis push | Directs sur le serveur |
| Branches | Légères, instantanées | Coûteuses (copie complète) |
| Réseau requis | Non (sauf push/pull) | Oui pour chaque opération |
| Modèle de stockage | Snapshots | Diffs (deltas) |
Pourquoi Git s'est imposé ? Vitesse, intégrité des données (SHA-1/SHA-256),
modèle distribué et surtout la légèreté des branches. GitHub, GitLab et Bitbucket
ont ensuite démocratisé son usage au niveau mondial.
2. Configuration initiale
Avant votre premier commit, Git a besoin de savoir qui vous êtes.
Ces informations apparaîtront dans chaque commit que vous créerez.
Identité globale
# Définir le nom d'auteur (global = tous les dépôts)
git config --global user.name "Prénom Nom"
# Définir l'email
git config --global user.email "prenom.nom@exemple.com"
Éditeur par défaut
# VS Code (recommandé)
git config --global core.editor "code --wait"
# Vim
git config --global core.editor vim
# Nano
git config --global core.editor nano
Branche par défaut
# Nommer "main" la branche initiale (convention moderne)
git config --global init.defaultBranch main
Fin de ligne (Windows)
# Windows : convertir CRLF → LF en commit, LF → CRLF en checkout
git config --global core.autocrlf true
# Linux/macOS : convertir CRLF → LF uniquement
git config --global core.autocrlf input
Afficher et vérifier la configuration
# Lister toutes les valeurs avec leur origine
git config --list
# Lister uniquement la config globale
git config --global --list
# Lire une valeur précise
git config user.name
# Modifier la config dans l'éditeur
git config --global --edit
Niveaux de configuration
| Niveau | Fichier | Portée | Flag |
| Système | /etc/gitconfig | Tous les utilisateurs | --system |
| Utilisateur | ~/.gitconfig | Tous vos dépôts | --global |
| Projet | .git/config | Ce dépôt uniquement | --local |
Priorité : --local > --global > --system.
La valeur la plus spécifique l'emporte toujours.
3. Cycle de vie des fichiers
Tout fichier dans un dépôt Git passe par plusieurs états.
Comprendre ce cycle est fondamental pour maîtriser Git.
Les 4 états d'un fichier
| État | Signification | Commande typique |
| Untracked | Fichier nouveau, inconnu de Git | git add fichier |
| Modified | Connu de Git, modifié depuis dernier commit | git add fichier |
| Staged | Ajouté à l'index, prêt pour le commit | git commit -m "..." |
| Committed | Sauvegardé dans l'historique Git | — |
Schéma des transitions
┌─────────────────────────────────────────────────────────────┐
│ Working Directory Staging Area (Index) Repository │
│ │
│ [Untracked] │
│ │ │
│ │ git add ──────────→ [Staged] │
│ │ │ │
│ [Modified] │ git commit ──────────→ [Committed]
│ │ │ │
│ │ git add ──────────→ [Staged] │
│ │ │ │
│ ←── git restore ────────────┘ │
│ ←── git restore --staged ──────────────────────────────│
└─────────────────────────────────────────────────────────────┘
Les 3 zones de Git
| Zone | Aussi appelée | Rôle |
| Working Directory | Working Tree | Les fichiers que vous éditez dans votre éditeur |
| Staging Area | Index / Cache | Zone de préparation du prochain commit |
| Repository | .git/objects | Base de données des commits (historique permanent) |
git status — lire l'état
git status
# Exemple de sortie :
On branch main
Changes to be committed: ← Staged (vert)
(use "git restore --staged ..." to unstage)
new file: src/app.js
Changes not staged for commit: ← Modified (rouge)
(use "git add ..." to update what will be committed)
modified: README.md
Untracked files: ← Untracked (rouge)
notes.txt
# Version courte (-s = --short)
git status -s
# Légende : M = modified A = added ?? = untracked D = deleted
M README.md
A src/app.js
?? notes.txt
Bonne pratique : Faites git status très souvent — avant un commit,
après un merge, après un pull. C'est votre tableau de bord Git.
4. Commandes fondamentales
Initialiser un dépôt
# Créer un nouveau dépôt dans le répertoire courant
git init
# Créer un dépôt dans un nouveau dossier
git init mon-projet
cd mon-projet
# Résultat : création du dossier .git/ contenant la base de données Git
Cloner un dépôt existant
# Cloner depuis GitHub (HTTPS)
git clone https://github.com/utilisateur/repo.git
# Cloner dans un dossier avec un nom spécifique
git clone https://github.com/utilisateur/repo.git mon-dossier
# Cloner via SSH (avec clé SSH configurée)
git clone git@github.com:utilisateur/repo.git
# Cloner uniquement la branche main (plus rapide)
git clone --branch main --single-branch https://github.com/utilisateur/repo.git
Ajouter des fichiers à l'index (staging)
# Ajouter un fichier précis
git add index.html
# Ajouter plusieurs fichiers
git add src/app.js src/utils.js
# Ajouter tous les fichiers du répertoire courant
git add .
# Ajouter tous les fichiers .js
git add *.js
# Mode interactif (choisir ligne par ligne)
git add -p fichier.js
Créer un commit
# Commit avec message inline
git commit -m "feat: ajouter la page d'accueil"
# Commit en ouvrant l'éditeur pour un message long
git commit
# Ajouter les fichiers trackés ET committer en une seule commande
git commit -am "fix: corriger le calcul du total"
# Modifier le dernier commit (message ou fichiers) — avant push !
git commit --amend -m "feat: ajouter la page d'accueil (avec nav)"
Conventional Commits (standard industriel)
| Type | Usage | Exemple |
feat | Nouvelle fonctionnalité | feat: ajouter authentification OAuth |
fix | Correction de bug | fix: corriger le crash au login |
docs | Documentation | docs: mettre à jour le README |
style | Formatage (pas de logique) | style: corriger l'indentation |
refactor | Réécriture sans changement fonctionnel | refactor: extraire la fonction calcTax |
test | Ajout/correction de tests | test: ajouter tests unitaires User |
chore | Maintenance (build, deps) | chore: mettre à jour les dépendances |
git commit --amend réécrit l'historique. Ne l'utilisez
jamais sur un commit déjà poussé (push) sur un dépôt partagé —
cela cassera l'historique de vos collègues.
5. Inspecter l'historique
git log — consulter les commits
# Log classique (verbose)
git log
# Log condensé sur une ligne par commit
git log --oneline
# Log avec graphe des branches
git log --oneline --graph --all
# Exemple de sortie :
* a3f8c1d (HEAD -> main) feat: ajouter formulaire contact
* 7b2e4a9 fix: corriger la validation email
* 1c9d5f2 feat: page d'accueil responsive
* 0e8b3c1 chore: initialiser le projet
# Afficher les N derniers commits
git log -5
# Filtrer par auteur
git log --author="Jean"
# Filtrer par date
git log --since="2024-01-01" --until="2024-12-31"
# Rechercher dans les messages de commit
git log --grep="feat"
# Log d'un fichier spécifique
git log --oneline src/app.js
git diff — voir les modifications
# Diff Working Directory vs Staging (non stagé)
git diff
# Diff Staging vs dernier commit (ce qui sera commité)
git diff --staged
# Diff entre deux commits
git diff HEAD~1 HEAD
# Diff entre deux branches
git diff main..feature/login
# Diff d'un fichier précis
git diff HEAD~2 -- src/app.js
git show — inspecter un commit
# Voir les détails du dernier commit
git show
# Voir un commit par son hash
git show a3f8c1d
# Voir un fichier à un commit précis
git show HEAD~1:src/app.js
Références relatives
| Référence | Signification |
HEAD | Le commit courant (là où vous êtes) |
HEAD~1 ou HEAD^ | Le commit parent (un avant HEAD) |
HEAD~3 | 3 commits avant HEAD |
main~2 | 2 commits avant le tip de main |
a3f8c1d | Commit identifié par son hash SHA |
Astuce : git log --oneline --graph --all --decorate est votre
meilleure commande pour avoir une vue d'ensemble de l'historique.
Créez un alias : git config --global alias.lg "log --oneline --graph --all --decorate"
puis tapez simplement git lg.
6. Annuler des changements
Git offre plusieurs façons d'annuler des modifications, selon leur état
(non stagé, stagé ou commité). Il est crucial de choisir la bonne commande.
Annuler dans le Working Directory
# Annuler les modifications d'un fichier (retour au dernier commit)
git restore fichier.js
# Annuler toutes les modifications non stagées
git restore .
# Ancienne syntaxe (toujours valide)
git checkout -- fichier.js
Désindexer un fichier (unstage)
# Retirer un fichier de la staging area (garde les modifications)
git restore --staged fichier.js
# Ancienne syntaxe
git reset HEAD fichier.js
Annuler des commits avec git reset
# --soft : annule le commit, garde les fichiers stagés
git reset --soft HEAD~1
# --mixed (défaut) : annule le commit, désindexe mais garde les modifs
git reset HEAD~1
# --hard : annule le commit ET efface toutes les modifications !
git reset --hard HEAD~1 ⚠ DESTRUCTIF
Annuler proprement avec git revert
# Créer un nouveau commit qui inverse le dernier commit
git revert HEAD
# Inverser un commit spécifique (sans ouvrir l'éditeur)
git revert a3f8c1d --no-edit
# Revert de plusieurs commits
git revert HEAD~3..HEAD
Mettre de côté avec git stash
# Sauvegarder les modifications non commitées
git stash
# Stash avec un message descriptif
git stash push -m "WIP: refactoring du formulaire"
# Lister les stashs
git stash list
# Réappliquer le dernier stash et le supprimer
git stash pop
# Réappliquer sans supprimer
git stash apply stash@{1}
Tableau comparatif des méthodes d'annulation
| Commande | Cible | Garde les modifs | Réécrit l'historique | Danger |
git restore fichier | Working Dir | Non | Non (pas de commit) | Moyen |
git restore --staged | Staging Area | Oui | Non | Faible |
git reset --soft | Commit | Oui (stagés) | Oui | Moyen |
git reset --mixed | Commit | Oui (non stagés) | Oui | Moyen |
git reset --hard | Commit + fichiers | Non | Oui | Élevé ! |
git revert | Commit (nouveau) | N/A | Non | Faible |
git stash | Working Dir + Staging | Oui (dans stash) | Non | Faible |
Règle d'or : Utilisez git revert pour annuler des commits
déjà partagés (pusés). Utilisez git reset uniquement pour
des commits locaux. La différence : revert crée un nouveau commit
visible, reset réécrit l'historique.
Récupérer après un reset --hard : Pas de panique !
git reflog garde une trace de tous vos déplacements HEAD.
Utilisez git reset --hard <hash-du-reflog> pour revenir en arrière.