Git
Git est le fondement du logiciel moderne. En 2025, des fonctionnalités comme Sparse Checkout et Scalar (pour les monorepos) deviennent courantes.
Quand l'utiliser
- Branchement et collaboration : Gestion de l'isolation des fonctionnalités, pull requests, développement trunk-based et revues de code au sein d'équipes réparties.
- Réécriture et nettoyage de l'historique : Linéarisation des graphes de commits, écrasement des commits en cours et édition des messages via
git rebase -iavant la fusion dans les branches principales. - Chasse automatisée aux bogues : Isolement des commits introduisant une régression sur des milliers de révisions via la recherche binaire avec
git bisect. - Contextes d'espace de travail simultanés : Travail sur des correctifs urgents sans avoir à mettre de côté ou changer de contexte de branche avec
git worktree. - Passage à l'échelle des grands dépôts : Optimisation des performances dans les monorepos massifs avec Git Sparse Checkout, Scalar et les clones superficiels.
Démarrage rapide
# Cloner le dépôt et créer une nouvelle branche de fonctionnalité
git clone https://github.com/monorg/projet.git
cd projet
# Créer et basculer sur une nouvelle branche avec la commande moderne
git switch -c feature/flux-auth
# Stager, commiter et pousser avec suivi amont
git add .
git commit -m "feat(auth): implémenter le flux d'autorisation oauth2"
git push -u origin feature/flux-auth
Concepts fondamentaux
L'architecture des 3 arbres (Working Tree, Index, HEAD)
Git gère les fichiers à travers trois états distincts plutôt que de simplement suivre les modifications entre révisions :
# 1. Working Tree : Fichiers modifiés non commités dans votre éditeur
echo "export const API_URL = 'https://api.v2.internal';" >> config.ts
# 2. Index (Zone de staging) : Contenu préparé pour le prochain commit
git add config.ts
# 3. HEAD : Le dernier instantané commité sur la branche active
git diff --staged # Inspecter la différence entre Staging et HEAD
git commit -m "chore(config): mettre à jour le point de terminaison API interne"
Graphe acyclique dirigé (DAG) et objets immuables
Chaque commit dans Git est un nœud immuable pointant vers des hachages parents et un arbre racine d'instantanés de blobs.
# Inspecter l'objet brut derrière tout hachage de commit ou HEAD
git cat-file -p HEAD
# Sortie :
# tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
# parent 8f3d1e1c3a628a58a98b47cf7d12a9e32049e712
# author Alice <[email protected]> 1727420400 +0000
# committer Alice <[email protected]> 1727420400 +0000
#
# feat(auth): implémenter le flux d'autorisation oauth2
Navigation moderne entre branches (git switch vs git restore)
Git moderne désambiguïse la commande surchargée git checkout en opérations dédiées :
# Changement de branche (remplace git checkout <branche>)
git switch main
git switch -c feature/paiements # Créer et basculer
# Restauration de fichier (remplace git checkout -- <fichier>)
git restore src/app.ts # Abandonner les modifications non commitées du répertoire de travail
git restore --staged src/app.ts # Désindexer le fichier de l'index vers le répertoire de travail
Stratégies Rebase vs Merge
- Merge (
git merge <branche>) : Préserve le contexte historique complet avec un commit de fusion à deux parents. Idéal pour intégrer des branches de version à longue durée de vie. - Rebase (
git rebase <amont>) : Rejoue les commits thématiques de manière linéaire sur le HEAD amont, empêchant les graphes enchevêtrés. Idéal pour nettoyer les branches de fonctionnalité avant la revue de PR.
# Rebaser proprement la branche de fonctionnalité sur le dernier main
git switch feature/flux-auth
git fetch origin main
git rebase origin/main
Modèles courants
Développement multi-branches avec Git Worktrees
Problème : Mettre de côté le travail non commité pour basculer de branche afin de corriger un bogue de production urgent.
Solution : Extraire plusieurs branches dans des répertoires séparés simultanément :
# Créer un dossier worktree parallèle pour la branche de correctif
git worktree add ../branche-correctif main
# Travailler sur le correctif dans un répertoire séparé sans toucher à l'espace de travail actuel
cd ../branche-correctif
git commit -am "fix: corriger une vulnérabilité d'authentification critique"
git push origin branche-correctif
# Nettoyer le worktree une fois terminé
cd ../projet
git worktree remove ../branche-correctif
Rebase interactif pour un historique propre des pull requests
Problème : La branche de fonctionnalité contient des dizaines de commits désordonnés du type "WIP", "correction ortho" ou "point de contrôle". Solution : Écraser et nettoyer l'historique de manière interactive avant d'ouvrir une pull request.
# Rebaser les 4 derniers commits de manière interactive
git rebase -i HEAD~4
# Dans l'éditeur interactif :
# pick 8f3d1e1 feat(auth): ajouter la génération de jeton
# squash 4b825dc corriger l'orthographe dans le payload du jeton
# squash a1c94e2 ajouter l'import manquant
# reword 91f7a02 feat(auth): ajouter le point de terminaison du jeton d'actualisation
Chasse automatisée aux régressions avec Git Bisect
Problème : Un bogue a été introduit quelque part parmi 500 commits, mais le commit exact est inconnu. Solution : Lancer une recherche binaire avec un script d'exécution de test automatisé.
# Démarrer une session bisect
git bisect start
git bisect bad HEAD # Le HEAD actuel est cassé
git bisect good v2.1.0 # v2.1.0 était connu comme fonctionnel
# Exécuter automatiquement le script de test à chaque étape du bisect
git bisect run npm test -- --runInBand
# Git se termine au premier commit exact qui a cassé la suite de tests
git bisect reset
Bonnes pratiques (2026)
À faire :
- Utiliser
git switchetgit restore: Éviter legit checkoutsurchargé pour prévenir les changements de branche ou les écrasements de fichiers accidentels. - Pousser avec
--force-with-lease: Se protéger contre l'écrasement des commits de collègues sur les branches distantes. - Activer la maintenance en arrière-plan : Exécuter
git maintenance startpour optimiser les packfiles, les graphes de commits et les performances de fetch. - Signer les commits avec SSH / GPG : Garantir l'authenticité de la paternité des commits dans les pipelines de production.
- Écrire des commits conventionnels : Utiliser des préfixes standardisés (
feat:,fix:,chore:,refactor:) pour automatiser le versionnage sémantique et les journaux de modifications.
À ne pas faire :
- Ne pas forcer le push sur les branches protégées : Ne jamais réécrire l'historique sur
main,masterou les branches de version partagées. - Ne pas commiter de secrets ou d'identifiants : Utiliser
.gitignoreet git-secrets/trufflehog ; une fois commités, les identifiants persistent dans les blobs des packfiles même s'ils sont supprimés ultérieurement. - Ne pas utiliser directement de gros fichiers binaires : Stocker les gros poids de modèles ou les médias dans Git LFS (Large File Storage) ou S3.
- Ne pas fusionner des arbres de travail sales : Mettre de côté (stash) ou commiter les modifications avant de tirer (pull) ou de rebaser pour éviter des conflits de fichiers accidentels.
Dépannage
| Erreur | Cause | Solution |
|---|---|---|
fatal: refusing to merge unrelated histories | Tirage depuis un dépôt initialisé indépendamment sans commit racine partagé. | Exécuter git pull origin main --allow-unrelated-histories. |
HEAD detached at ... | Extraction d'un hachage de commit spécifique plutôt qu'un nom de branche. | Créer une branche à partir de la position actuelle : git switch -c branche-recuperation. |
Merge conflict in file.txt | Des commits concurrents ont modifié des lignes identiques dans des branches opposées. | Résoudre les marqueurs de conflit (<<<<<<<), stagifier le fichier (git add), puis exécuter git commit. |