🌿 Git Maîtrisé
Versioning, Branches & Scénarios Réels
🔥 Mise en situation : L'enfer du fichier "Final_v2_v3_OK.docx"
Avant Git, comment travaillait-on à plusieurs sur un code ? On utilisait un dossier partagé sur le réseau de l'entreprise. Alice modifiait le fichier "Index.html". Bob modifiait le même fichier en même temps. En sauvegardant, Bob écrasait le travail d'Alice. Résultat : une perte de données désastreuse.
Pour éviter cela, on créait des copies : "Index_Alice_vendredi.html", "Index_FINAL_FINAL_v3.html". Le projet devenait un dépotoir incompréhensible. Git résout définitivement ce problème archaïque en permettant à des milliers de développeurs de collaborer sur la même ligne de code sans jamais l'écraser sauvagement.
⚠️ Rappel : Versioning "Distribué" VS "Centralisé"
Git est un système de contrôle de version Décentralisé (Distribué).
Dans les anciens systèmes (comme SVN), un unique serveur central stockait tout l'historique du code. Si le serveur crachait ou si vous preniez l'avion (sans WiFi), impossible de voir les anciennes versions ou de valider son travail.
Avec Git, chaque développeur possède un clone intégral (100%) de l'historique et du code source sur son propre ordinateur. Vous pouvez "commiter" dans le TGV sans internet, et le système survit même si le serveur GitLab central explose.
⏳ Analogie : La Machine à Voyager dans le Temps
Imaginez Git comme une sauvegarde temporelle (Save State) de votre jeu vidéo ou de votre projet. Chaque commit est une photo instantanée. Si vous cassez tout la veille d'une livraison, vous pouvez littéralement remonter le temps jusqu'à l'instant précis du vendredi 15h00 pour rétablir votre code tel qu'il était, sans perdre le reste. Les branches sont des univers parallèles où vous pouvez expérimenter des fonctionnalités folles sans empoisonner la dimension principale (le `main`).
📖 Pourquoi Git est le standard absolu ?
Avant Git, les développeurs utilisaient des systèmes centralisés (SVN, Perforce). Si le serveur tombait, tout le monde s'arrêtait de travailler. Git est distribué :
- Travail Offline : Chaque développeur a l'historique complet sur sa machine.
- Branches légères : Créer une branche prend 1ms (c'est juste un pointeur).
- Intégrité totale : Chaque commit est signé par un hash SHA-1 (impossible de modifier l'histoire sans que ça se voie).
- Agilité : Permet de tester des idées folles sans polluer le code principal.
En DevOps, Git est la Source de Vérité. Si c'est pas dans Git, ça n'existe pas en production.
💡 Le saviez-vous ?
Linus Torvalds (créateur de Linux) a écrit la première version de Git en seulement 2 semaines en 2005. Il était furieux d'avoir perdu l'accès gratuit à BitKeeper et voulait un outil qui soit "tout l'inverse de CVS/SVN".
Aujourd'hui, 94% des développeurs utilisent Git.
📊 A. Anatomie du Flux Git
⌨️ B. Commandes Essentielles
| Commande | Action | Exemple |
|---|---|---|
git clone |
Copier un repo distant en local | git clone git@github.com:user/repo.git |
git add |
Ajouter au staging (préparer le commit) | git add . ou git add fichier.js |
git commit |
Sauvegarder dans l'historique local | git commit -m "feat: add login" |
git push |
Envoyer les commits vers le remote | git push origin main |
git pull |
Récupérer les changements du remote | git pull origin main |
git branch |
Lister / Créer des branches | git branch feature/login |
git checkout |
Changer de branche / Restaurer fichier | git checkout -b feature/api |
git merge |
Fusionner une branche dans l'actuelle | git merge feature/login |
git rebase |
Réécrire l'historique (plus propre que merge) | git rebase main |
git stash |
Mettre de côté les modifs temporairement | git stash puis git stash pop |
git log |
Voir l'historique des commits | git log --oneline -10 |
git reset |
Annuler des commits (⚠️ Dangereux) | git reset --soft HEAD~1 |
🎬 C. Scénarios Réels (3 Cas)
🧑💻 Scénario 1 : Solo Developer
Vous travaillez seul sur un projet perso.
git clone - Récupérer le repogit checkout -b feature/ma-fonctionnalité - Créer une branchegit add . && git commit -m "feat: ..." - Commitgit push origin feature/ma-fonctionnalité - Push👥 Scénario 2 : Équipe (Feature Branch)
Vous développez en parallèle avec d'autres devs.
git pull origin main - Toujours partir d'un main à jourgit checkout -b feature/api-users - Votre branchegit fetch && git rebase origin/main - Se resynchroniser AVANT la PR
git push -f origin feature/api-users - Force push après rebase🚨 Scénario 3 : Hotfix en Production
Bug critique en prod, il faut corriger MAINTENANT.
git checkout main && git pull - Partir de la prod actuellegit checkout -b hotfix/fix-crash-login - Branche hotfixgit commit -m "fix: resolve crash on login"git cherry-pick <commit-hash> - Reporter le fix sur les autres
branches si nécessaire📊 Merge vs Rebase : Le Grand Débat
🌱 git merge
- Non-destructif : Préserve l'historique complet et chronologique.
- Traçabilité : On voit exactement quand les branches ont fusionné.
- Pollution : Crée beaucoup de "Merge commits" (historique en spaghettis).
- Conflits : Une seule grosse résolution de conflits à la fin.
🚀 git rebase
- Historique Linéaire : Pas de commits de merge inutiles. C'est propre !
- Plus lisible : Plus facile à suivre pour les autres développeurs.
- Destructif : Réécrit l'histoire (⚠️ Ne jamais faire sur une branche publique partagee).
- Conflits : On résout les conflits commit par commit (plus granulaire).
📊 Cas d'étude : Résolution de Conflits Explosive
Contexte : Deux équipes ont travaillé sur la même refacto majeure pendant 2 semaines sans se synchroniser. Au moment du merge : l'enfer.
Stratégie de survie :
- Isolation : On ne résout pas ça sur le main. On crée une branche de "sync".
- Communication : Les deux leads techniques s'asseyent ensemble (Pair Programming).
- Outils : Utilisation de
git mergetoolavec VS Code ou IntelliJ pour visualiser les "3-way merges". - Granularité : Rebase interactif (
git rebase -i) pour squasher les petits commits avant de merger.
Résultat : Migration réussie. Leçon Apprise : Synchronisez-vous
tous les jours (git pull fréquent) pour éviter les "Merges de la mort".
🔄 À Retenir - Git Mastery
- Git est distribué : Pas de SPOF (Single Point of Failure).
- L'Atomicité : Un commit = une seule chose (une feature, un fix).
- Conventional Commits : Utilisez
feat:,fix:,docs:pour un historique clair. - Protection de Branche : Interdire de push directement sur
main. - PR / Code Review : Git est avant tout un outil de collaboration et de qualité.
Git Flow vs Trunk Based
- Trunk-Based (Moderne) : Une seule branche
main. PRs ultra-courtes (< 24h). Nécessite tests solides. - Trunk-Based (Legacy) : Branches
develop,release,hotfix. Crée des "Merge Hells".
Conventional Commits
Standardiser les messages pour automatiser le Changelog.
fix(api): resolve timeout on user fetch
chore: update dependencies
🔧 D. Git Under the Hood
Git n'est pas magique. C'est un système de fichiers adressable par le contenu. Tout est stocké dans
le
dossier .git.
.git/ ├── HEAD # Pointeur actuel (ref: refs/heads/main) ├── config # Config locale (remote url, user) ├── index # La zone de Staging (binaire) ├── refs/ # Pointeurs (branches, tags) │ ├── heads/ # Branches locales (main contient le hash) │ └── remotes/ # Branches distantes └── objects/ # LA BASE DE DONNÉES ├── a1/ # Hash SHA-1 (les 2 premiers chars) └── ...
Les 3 Objets Git
- Blob : Le contenu d'un fichier (sans le nom).
- Tree : Un dossier. Associe des noms de fichiers à des Blobs.
- Commit : Metadonnées (Auteur, Date, Message) + Pointeur vers un Tree Racine + Pointeur vers le Parent.
🕵️ E. Advanced Debugging
Git Bisect
Trouver le commit qui a introduit un bug par dichotomie.
git bisect start
git bisect bad (ici)
git bisect good v1.0
Git vous balade dans l'historique jusqu'au coupable.
Git Reflog
Vous avez fait un reset --hard et tout perdu ?
NON ! git reflog liste TOUS les mouvements de HEAD (même les
annulés).
git reset --hard HEAD@{1} pour revenir.
Git Rerere
"Reuse Recorded Resolution".
Git se souvient comment vous avez résolu un conflit. S'il se reproduit (ex: rebase interactif),
il
le résout tout seul.
🛑 Troubleshooting : Oups, j'ai tout cassé !
- Commit sur la mauvaise branche :
git reset --soft HEAD~1(annule le commit mais garde les modifs), puisgit checkout bonne-brancheet re-commit. - Push de données sensibles (mot de passe) : N'utilisez SURTOUT PAS un simple git rm. Utilisez BFG Repo-Cleaner ou
git filter-repopour réécrire l'historique distant. CHANGER LE MOT DE PASSE IMMEDIATEMENT. - Conflits de Merge infinis :
git merge --abortougit rebase --abortpour tout annuler et revenir à l'état sain.
🚅 F. Performance & Large Files
🐘 Git LFS (Large File Storage)
Git est nul pour les gros fichiers binaires (PSD, MP4). Chaque modif re-stocke tout le fichier.
Solution : Git stocke un pointeur texte (2kb), et le fichier réel va dans un stockage à part (LFS Store).
git lfs track "*.psd"
🤏 Partial Clone & Shallow Clone
Le repo fait 10Go ? Pas besoin de tout télécharger.
- Shallow (
--depth 1) : Juste le dernier commit (idéal pour CI). - Partial (
--filter=blob:none) : Télécharge l'historique mais PAS les fichiers. Les fichiers sont téléchargés à la demande (au checkout).
GitOps = IaC + PRs + Convergence Agent.
Au lieu de faire kubectl apply -f file.yaml (impératif, manuel), vous commitez le
fichier yaml dans Git.
ArgoCD (l'agent dans le cluster) voit le changement Git, compare avec l'état réel, et force la synchronisation.
Git (Désiré) == Cluster (Réel)