Modèles de Workflow Git
Bonnes pratiques pour le contrôle de version Git, les stratégies de branchement et le développement collaboratif.
Quand Activer
- Mise en place d'un workflow Git pour un nouveau projet
- Choix d'une stratégie de branchement (GitFlow, trunk-based, GitHub flow)
- Rédaction de messages de commit et de descriptions de PR
- Résolution de conflits de fusion
- Gestion des releases et des tags de version
- Intégration de nouveaux membres de l'équipe aux pratiques Git
Stratégies de Branchement
GitHub Flow (Simple, Recommandé pour la Plupart des Cas)
Idéal pour le déploiement continu et les équipes petites à moyennes.
main (protégée, toujours déployable)
│
├── feature/user-auth → PR → fusionner dans main
├── feature/payment-flow → PR → fusionner dans main
└── fix/login-bug → PR → fusionner dans main
Règles :
mainest toujours déployable- Créez des branches de fonctionnalités à partir de
main - Ouvrez une Pull Request dès que prête pour révision
- Après approbation et CI réussie, fusionnez dans
main - Déployez immédiatement après la fusion
Développement Trunk-Based (Équipes à Haute Vélocité)
Idéal pour les équipes avec CI/CD solide et feature flags.
main (tronc)
│
├── feature de courte durée (1-2 jours max)
├── feature de courte durée
└── feature de courte durée
Règles :
- Tout le monde commit sur
mainou des branches de très courte durée - Les feature flags masquent le travail incomplet
- La CI doit réussir avant la fusion
- Déployez plusieurs fois par jour
GitFlow (Complexe, Piloté par les Cycles de Release)
Idéal pour les releases planifiées et les projets d'entreprise.
main (releases de production)
│
└── develop (branche d'intégration)
│
├── feature/user-auth
├── feature/payment
│
├── release/1.0.0 → fusionner dans main et develop
│
└── hotfix/critical → fusionner dans main et develop
Règles :
maincontient uniquement du code prêt pour la productiondevelopest la branche d'intégration- Les branches de fonctionnalités partent de
developet fusionnent dansdevelop - Les branches de release partent de
developet fusionnent dansmainetdevelop - Les branches hotfix partent de
mainet fusionnent dansmainetdevelop
Quand Utiliser Quelle Stratégie
| Stratégie | Taille de l'Équipe | Cadence de Release | Idéal Pour |
|---|---|---|---|
| GitHub Flow | Toute taille | Continue | SaaS, applications web, startups |
| Trunk-Based | 5+ expérimentés | Plusieurs/jour | Équipes à haute vélocité, feature flags |
| GitFlow | 10+ | Planifiée | Entreprise, secteurs réglementés |
Messages de Commit
Format des Commits Conventionnels
<type>(<scope>): <sujet>
[corps optionnel]
[pied de page optionnel]
Types
| Type | Utilisation | Exemple |
|---|---|---|
feat | Nouvelle fonctionnalité | feat(auth): ajouter connexion OAuth2 |
fix | Correction de bug | fix(api): gérer la réponse nulle dans le point de terminaison utilisateur |
docs | Documentation | docs(readme): mettre à jour les instructions d'installation |
style | Formatage, sans changement de code | style: corriger l'indentation dans le composant de connexion |
refactor | Refactorisation de code | refactor(db): extraire le pool de connexions vers un module |
test | Ajout/mise à jour de tests | test(auth): ajouter des tests unitaires pour la validation de token |
chore | Tâches de maintenance | chore(deps): mettre à jour les dépendances |
perf | Amélioration de performance | perf(query): ajouter un index à la table des utilisateurs |
ci | Modifications CI/CD | ci: ajouter le service PostgreSQL au workflow de test |
revert | Annulation d'un commit précédent | revert: annuler "feat(auth): ajouter connexion OAuth2" |
Exemples de Bons et Mauvais Commits
# MAUVAIS : Vague, sans contexte
git commit -m "trucs corrigés"
git commit -m "mises à jour"
git commit -m "WIP"
# BON : Clair, spécifique, explique pourquoi
git commit -m "fix(api): réessayer les requêtes sur 503 Service Indisponible
L'API externe renvoie occasionnellement des erreurs 503 pendant les heures de pointe.
Ajout d'une logique de réessai avec backoff exponentiel et maximum 3 tentatives.
Fermer #123"
Modèle de Message de Commit
Créez .gitmessage à la racine du dépôt :
# <type>(<scope>): <sujet>
# # Types : feat, fix, docs, style, refactor, test, chore, perf, ci, revert
# Scope : api, ui, db, auth, etc.
# Sujet : mode impératif, pas de point, max 50 caractères
#
# [corps optionnel] - expliquez pourquoi, pas quoi
# [pied de page optionnel] - Breaking changes, ferme #issue
Activez avec : git config commit.template .gitmessage
Fusion vs Rebase
Fusion (Préserve l'Historique)
# Crée un commit de fusion
git checkout main
git merge feature/user-auth
# Résultat :
# * commit de fusion
# |\
# | * commits de la feature
# |/
# * commits de main
À utiliser quand :
- Fusionner des branches de fonctionnalités dans
main - Vous voulez préserver l'historique exact
- Plusieurs personnes ont travaillé sur la branche
- La branche a été poussée et d'autres ont basé leur travail dessus
Rebase (Historique Linéaire)
# Réécrit les commits de la feature sur la branche cible
git checkout feature/user-auth
git rebase main
# Résultat :
# * commits de la feature (réécrits)
# * commits de main
À utiliser quand :
- Mettre à jour votre branche feature locale avec le dernier
main - Vous voulez un historique linéaire et propre
- La branche est uniquement locale (non poussée)
- Vous êtes le seul à travailler sur la branche
Workflow Rebase
# Mettre à jour la branche feature avec le dernier main (avant PR)
git checkout feature/user-auth
git fetch origin
git rebase origin/main
# Corriger les conflits éventuels
# Les tests doivent toujours passer
# Forcer le push (uniquement si vous êtes le seul contributeur)
git push --force-with-lease origin feature/user-auth
Quand NE PAS Rebaser
# Ne JAMAIS rebaser les branches qui :
- Ont été poussées vers un dépôt partagé
- Sur lesquelles d'autres personnes ont basé leur travail
- Sont des branches protégées (main, develop)
- Sont déjà fusionnées
# Pourquoi : Le rebase réécrit l'historique, cassant le travail des autres
Workflow Pull Request
Format du Titre de PR
<type>(<scope>): <description>
Exemples :
feat(auth): ajouter le support SSO pour les utilisateurs entreprise
fix(api): résoudre une race condition dans le traitement des commandes
docs(api): ajouter la spécification OpenAPI pour les endpoints v2
Modèle de Description de PR
## Quoi
Brève description de ce que fait cette PR.
## Pourquoi
Expliquez la motivation et le contexte.
## Comment
Détails d'implémentation clés à souligner.
## Tests
- [ ] Tests unitaires ajoutés/mis à jour
- [ ] Tests d'intégration ajoutés/mis à jour
- [ ] Tests manuels effectués
## Captures d'écran (si applicable)
Captures d'écran avant/après pour les modifications UI.
## Checklist
- [ ] Le code respecte les directives de style du projet
- [ ] Auto-révision terminée
- [ ] Commentaires ajoutés pour la logique complexe
- [ ] Documentation mise à jour
- [ ] Aucun nouvel avertissement introduit
- [ ] Les tests passent localement
- [ ] Issues liées
Fermer #123
Checklist de Révision de Code
Pour les Réviseurs :
- Le code résout-il le problème énoncé ?
- Des cas limites ne sont-ils pas traités ?
- Le code est-il lisible et maintenable ?
- Y a-t-il suffisamment de tests ?
- Y a-t-il des problèmes de sécurité ?
- L'historique des commits est-il propre (squashé si nécessaire) ?
Pour les Auteurs :
- Auto-révision terminée avant de demander une révision
- CI réussie (tests, lint, typecheck)
- La taille de la PR est raisonnable (<500 lignes idéal)
- Liée à une seule fonctionnalité/correction
- La description explique clairement le changement
Résolution de Conflits
Identifier les Conflits
# Vérifier les conflits avant fusion
git checkout main
git merge feature/user-auth --no-commit --no-ff
# En cas de conflits, Git affichera :
# CONFLIT (contenu) : Conflit de fusion dans src/auth/login.ts
# La fusion automatique a échoué ; corrigez les conflits puis validez le résultat.
Résoudre les Conflits
# Voir les fichiers en conflit
git status
# Afficher les marqueurs de conflit dans le fichier
# <<<<<<< HEAD
# contenu de main
# =======
# contenu de la branche feature
# >>>>>>> feature/user-auth
# Option 1 : Résolution manuelle
# Modifier le fichier, supprimer les marqueurs, garder le contenu correct
# Option 2 : Utiliser un outil de fusion
git mergetool
# Option 3 : Accepter un côté
git checkout --ours src/auth/login.ts # Garder la version main
git checkout --theirs src/auth/login.ts # Garder la version feature
# Après résolution, indexer et valider
git add src/auth/login.ts
git commit
Stratégies de Prévention des Conflits
# 1. Garder les branches de fonctionnalités petites et de courte durée
# 2. Rebaser fréquemment sur main
git checkout feature/user-auth
git fetch origin
git rebase origin/main
# 3. Communiquer avec l'équipe sur les fichiers partagés
# 4. Utiliser des feature flags au lieu de branches de longue durée
# 5. Examiner et fusionner les PR rapidement
Gestion des Branches
Conventions de Nommage
# Branches de fonctionnalités
feature/user-authentication
feature/JIRA-123-payment-integration
# Correctifs de bugs
fix/login-redirect-loop
fix/456-null-pointer-exception
# Correctifs urgents (problèmes de production)
hotfix/critical-security-patch
hotfix/database-connection-leak
# Releases
release/1.2.0
release/2024-01-hotfix
# Expériences/POCs
experiment/new-caching-strategy
poc/graphql-migration
Nettoyage des Branches
# Supprimer les branches locales fusionnées
git branch --merged main | grep -v "^\*\|main" | xargs -n 1 git branch -d
# Supprimer les références de suivi distant pour les branches distantes supprimées
git fetch -p
# Supprimer une branche locale
git branch -d feature/user-auth # Suppression sécurisée (uniquement si fusionnée)
git branch -D feature/user-auth # Forcer la suppression
# Supprimer une branche distante
git push origin --delete feature/user-auth
Workflow Stash
# Sauvegarder le travail en cours
git stash push -m "WIP: authentification utilisateur"
# Lister les stashes
git stash list
# Appliquer le stash le plus récent
git stash pop
# Appliquer un stash spécifique
git stash apply stash@{2}
# Supprimer un stash
git stash drop stash@{0}
Gestion des Releases
Version Sémantique
MAJEUR.MINEUR.CORRECTIF
MAJEUR : Changements cassants
MINEUR : Nouvelles fonctionnalités, rétrocompatibles
CORRECTIF : Corrections de bugs, rétrocompatibles
Exemples :
1.0.0 → 1.0.1 (correctif : correction de bug)
1.0.1 → 1.1.0 (mineur : nouvelle fonctionnalité)
1.1.0 → 2.0.0 (majeur : changement cassant)
Création de Releases
# Créer un tag annoté
git tag -a v1.2.0 -m "Release v1.2.0
Fonctionnalités :
- Ajouter l'authentification utilisateur
- Implémenter la réinitialisation de mot de passe
Correctifs :
- Résoudre le problème de redirection de connexion
Changements Cassants :
- Aucun"
# Pousser le tag vers le dépôt distant
git push origin v1.2.0
# Lister les tags
git tag -l
# Supprimer un tag
git tag -d v1.2.0
git push origin --delete v1.2.0
Génération de Changelog
# Générer le changelog à partir des commits
git log v1.1.0..v1.2.0 --oneline --no-merges
# Ou utiliser conventional-changelog
npx conventional-changelog -i CHANGELOG.md -s
Configuration Git
Configurations Essentielles
# Identité de l'utilisateur
git config --global user.name "Votre Nom"
git config --global user.email "[email protected]"
# Nom de branche par défaut
git config --global init.defaultBranch main
# Comportement de pull (rebase au lieu de fusion)
git config --global pull.rebase true
# Comportement de push (pousser uniquement la branche courante)
git config --global push.default current
# Correction automatique des fautes de frappe
git config --global help.autocorrect 1
# Meilleur algorithme de diff
git config --global diff.algorithm histogram
# Sortie couleur
git config --global color.ui auto
Alias Utiles
# Ajouter à ~/.gitconfig
[alias]
co = checkout
br = branch
ci = commit
st = status
unstage = reset HEAD --
last = log -1 HEAD
visual = log --oneline --graph --all
amend = commit --amend --no-edit
wip = commit -m "WIP"
undo = reset --soft HEAD~1
contributors = shortlog -sn
Modèles Gitignore
# Dépendances
node_modules/
vendor/
# Sorties de build
dist/
build/
*.o
*.exe
# Fichiers d'environnement
.env
.env.local
.env.*.local
# IDE
.idea/
.vscode/
*.swp
*.swo
# Fichiers OS
.DS_Store
Thumbs.db
# Logs
*.log
logs/
# Couverture de tests
coverage/
# Cache
.cache/
*.tsbuildinfo
Workflows Courants
Démarrage d'une Nouvelle Fonctionnalité
# 1. Mettre à jour la branche main
git checkout main
git pull origin main
# 2. Créer une branche de fonctionnalité
git checkout -b feature/user-auth
# 3. Faire des modifications et commit
git add .
git commit -m "feat(auth): implémenter la connexion OAuth2"
# 4. Pousser vers le dépôt distant
git push -u origin feature/user-auth
# 5. Créer une Pull Request sur GitHub/GitLab
Mise à Jour d'une PR avec de Nouveaux Changements
# 1. Faire des modifications supplémentaires
git add .
git commit -m "feat(auth): ajouter la gestion des erreurs"
# 2. Pousser les mises à jour
git push origin feature/user-auth
Synchronisation d'un Fork avec le Dépôt Amont
# 1. Ajouter le dépôt amont remote (une fois)
git remote add upstream https://github.com/original/repo.git
# 2. Récupérer l'amont
git fetch upstream
# 3. Fusionner upstream/main dans votre main
git checkout main
git merge upstream/main
# 4. Pousser vers votre fork
git push origin main
Annulation d'Erreurs
# Annuler le dernier commit (garder les modifications)
git reset --soft HEAD~1
# Annuler le dernier commit (ignorer les modifications)
git reset --hard HEAD~1
# Annuler le dernier commit poussé vers le dépôt distant
git revert HEAD
git push origin main
# Annuler les modifications d'un fichier spécifique
git checkout HEAD -- chemin/vers/fichier
# Corriger le message du dernier commit
git commit --amend -m "Nouveau message"
# Ajouter un fichier oublié au dernier commit
git add fichier-oublie
git commit --amend --no-edit
Hooks Git
Hook Pre-Commit
#!/bin/bash
# .git/hooks/pre-commit
# Exécuter le linting
npm run lint || exit 1
# Exécuter les tests
npm test || exit 1
# Vérifier la présence de secrets
if git diff --cached | grep -E '(password|api_key|secret)'; then
echo "Secret possible détecté. Commit avorté."
exit 1
fi
Hook Pre-Push
#!/bin/bash
# .git/hooks/pre-push
# Exécuter la suite de tests complète
npm run test:all || exit 1
# Vérifier la présence de console.log
if git diff origin/main | grep -E 'console\.log'; then
echo "Supprimez les instructions console.log avant de pousser."
exit 1
fi
Anti-Patterns
# MAUVAIS : Commiter directement sur main
git checkout main
git commit -m "correction bug"
# BON : Utiliser des branches de fonctionnalités et des PR
# MAUVAIS : Commiter des secrets
git add .env # Contient des clés API
# BON : Ajouter au .gitignore, utiliser des variables d'environnement
# MAUVAIS : PRs géantes (1000+ lignes)
# BON : Décomposer en PRs plus petites et ciblées
# MAUVAIS : Messages de commit "Mise à jour"
git commit -m "mise à jour"
git commit -m "correction"
# BON : Messages descriptifs
git commit -m "fix(auth): résoudre la boucle de redirection après connexion"
# MAUVAIS : Réécriture de l'historique public
git push --force origin main
# BON : Utiliser revert pour les branches publiques
git revert HEAD
# MAUVAIS : Branches de fonctionnalités de longue durée (semaines/mois)
# BON : Garder les branches courtes (jours), rebaser fréquemment
# MAUVAIS : PRs sans description
git commit -m "trucs"
git commit -m "WIP"
# MAUVAIS : Mélanger plusieurs fonctionnalités dans une même branche
git commit -m "feat(auth): ajouter connexion"
git commit -m "feat(payment): ajouter traitement"
etc.
# BON : Une branche par fonctionnalité