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

SituationSans GitAvec Git
Revenir en arrièreCopier manuellement les fichiers…git checkout <hash>
Travailler à plusieursEnvoi de fichiers par emailBranches + merge automatisé
Savoir qui a modifié quoiImpossiblegit blame fichier.js
Tester une idée risquéeDupliquer le dossier projetgit branch experiment
Retrouver un bug introduitChercher manuellementgit bisect
Sauvegarder en cours de routeproject_v2_FINAL_bis.zipgit stash

Git vs SVN (centralisé)

CaractéristiqueGit (distribué)SVN (centralisé)
Historique completEn local (hors ligne)Sur le serveur uniquement
CommitsLocaux, puis pushDirects sur le serveur
BranchesLégères, instantanéesCoûteuses (copie complète)
Réseau requisNon (sauf push/pull)Oui pour chaque opération
Modèle de stockageSnapshotsDiffs (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

NiveauFichierPortéeFlag
Système/etc/gitconfigTous les utilisateurs--system
Utilisateur~/.gitconfigTous vos dépôts--global
Projet.git/configCe 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

ÉtatSignificationCommande typique
UntrackedFichier nouveau, inconnu de Gitgit add fichier
ModifiedConnu de Git, modifié depuis dernier commitgit add fichier
StagedAjouté à l'index, prêt pour le commitgit commit -m "..."
CommittedSauvegardé 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

ZoneAussi appeléeRôle
Working DirectoryWorking TreeLes fichiers que vous éditez dans votre éditeur
Staging AreaIndex / CacheZone de préparation du prochain commit
Repository.git/objectsBase 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)

TypeUsageExemple
featNouvelle fonctionnalitéfeat: ajouter authentification OAuth
fixCorrection de bugfix: corriger le crash au login
docsDocumentationdocs: mettre à jour le README
styleFormatage (pas de logique)style: corriger l'indentation
refactorRéécriture sans changement fonctionnelrefactor: extraire la fonction calcTax
testAjout/correction de teststest: ajouter tests unitaires User
choreMaintenance (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érenceSignification
HEADLe commit courant (là où vous êtes)
HEAD~1 ou HEAD^Le commit parent (un avant HEAD)
HEAD~33 commits avant HEAD
main~22 commits avant le tip de main
a3f8c1dCommit 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

CommandeCibleGarde les modifsRéécrit l'historiqueDanger
git restore fichierWorking DirNonNon (pas de commit)Moyen
git restore --stagedStaging AreaOuiNonFaible
git reset --softCommitOui (stagés)OuiMoyen
git reset --mixedCommitOui (non stagés)OuiMoyen
git reset --hardCommit + fichiersNonOuiÉlevé !
git revertCommit (nouveau)N/ANonFaible
git stashWorking Dir + StagingOui (dans stash)NonFaible
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.