Modèles de flux de travail Git
Bonnes pratiques pour le contrôle de version Git, les stratégies de branchement et le développement collaboratif.
Quand activer
- Configurer un flux de travail Git pour un nouveau projet
- Choisir une stratégie de branchement (GitFlow, trunk-based, GitHub flow)
- Rédiger des messages de commit et des descriptions de PR
- Résoudre des conflits de fusion
- Gérer les versions et les tags de version
- Intégrer de nouveaux membres de l'équipe aux pratiques Git
Stratégies de branchement
GitHub Flow (Simple, recommandé pour la plupart)
Idéal pour le déploiement continu et les équipes de petite à moyenne taille.
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éer des branches de fonctionnalités à partir de
main - Ouvrir une Pull Request lorsqu'elle est prête pour la révision
- Après approbation et succès de l'IC, fusionner dans
main - Déployer immédiatement après la fusion
Développement Trunk-Based (Équipes à haute vélocité)
Idéal pour les équipes disposant d'une solide IC/CD et de feature flags.
main (tronc)
│
├── branche de courte durée (1-2 jours max)
├── branche de courte durée
└── branche de courte durée
Règles :
- Tout le monde valide dans
mainou dans des branches de très courte durée - Les feature flags masquent le travail incomplet
- L'IC doit réussir avant la fusion
- Déployer plusieurs fois par jour
GitFlow (Complexe, axé sur les cycles de publication)
Idéal pour les publications planifiées et les projets d'entreprise.
main (versions 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 le code prêt pour la productiondevelopest la branche d'intégration- Les branches de fonctionnalités partent de
develop, fusionner dansdevelop - Les branches de publication partent de
develop, fusionner dansmainetdevelop - Les branches de correctif partent de
main, fusionner dansmainetdevelop
Quand utiliser quoi
| Stratégie | Taille d'équipe | Cadence de publication | Idéal pour |
|---|---|---|---|
| GitHub Flow | Toute | 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>(<portée>): <sujet>
[corps optionnel]
[pied de page optionnel(s)]
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, pas de changement de code | style: corriger l'indentation dans le composant de connexion |
refactor | Refactorisation de code | refactor(db): extraire le pool de connexions dans un module |
test | Ajout/mise à jour de tests | test(auth): ajouter des tests unitaires pour la validation du jeton |
chore | Tâches de maintenance | chore(deps): mettre à jour les dépendances |
perf | Amélioration des performances | perf(query): ajouter un index à la table des utilisateurs |
ci | Modifications IC/CD | ci: ajouter le service PostgreSQL au workflow de test |
revert | Annuler un commit précédent | revert: annuler "feat(auth): ajouter connexion OAuth2" |
Bons vs mauvais exemples
# 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 parfois des erreurs 503 pendant les heures de pointe.
Ajout d'une logique de réessai avec backoff exponentiel et max 3 tentatives.
Ferme #123"
Modèle de message de commit
Créer .gitmessage à la racine du dépôt :
# <type>(<portée>): <sujet>
# # Types : feat, fix, docs, style, refactor, test, chore, perf, ci, revert
# Portée : api, ui, db, auth, etc.
# Sujet : mode impératif, pas de point, 50 caractères max
#
# [corps optionnel] - expliquez pourquoi, pas quoi
# [pied de page optionnel] - Breaking changes, ferme #issue
Activer avec : git config commit.template .gitmessage
Fusion vs Rebasage
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 fonctionnalité
# |/
# * 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 pu baser leur travail dessus
Rebasage (Historique linéaire)
# Réécrit les commits de la fonctionnalité sur la branche cible
git checkout feature/user-auth
git rebase main
# Résultat :
# * commits de la fonctionnalité (réécrits)
# * commits de main
À utiliser quand :
- Mettre à jour votre branche de fonctionnalité locale avec la dernière version de
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 de rebasage
# Mettre à jour la branche de fonctionnalité avec la dernière version de main (avant PR)
git checkout feature/user-auth
git fetch origin
git rebase origin/main
# Corriger d'éventuels conflits
# Les tests devraient 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 sur 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 rebasage réécrit l'historique, ce qui casse le travail des autres
Workflow de Pull Request
Format du titre de PR
<type>(<portée>): <description>
Exemples :
feat(auth): ajouter la prise en charge SSO pour les utilisateurs entreprise
fix(api): résoudre une condition de concurrence dans le traitement des commandes
docs(api): ajouter la spécification OpenAPI pour les points de terminaison v2
Modèle de description de PR
## Quoi
Brève description de ce que fait cette PR.
## Pourquoi
Expliquer la motivation et le contexte.
## Comment
Détails d'implémentation clés qui méritent d'être soulignés.
## 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.
## Liste de vérification
- [ ] Le code suit les directives de style du projet
- [ ] Auto-révision effectuée
- [ ] Commentaires ajoutés pour la logique complexe
- [ ] Documentation mise à jour
- [ ] Aucun nouvel avertissement introduit
- [ ] Les tests passent localement
- [ ] Problèmes liés fermés
Ferme #123
Liste de vérification pour la révision de code
Pour les réviseurs :
- Le code résout-il le problème énoncé ?
- Y a-t-il des cas limites non traités ?
- Le code est-il lisible et maintenable ?
- Y a-t-il des tests suffisants ?
- 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 effectuée avant de demander une révision
- IC réussit (tests, lint, typecheck)
- La taille de la PR est raisonnable (<500 lignes idéalement)
- Liée à une seule fonctionnalité/correction
- La description explique clairement le changement
Résolution de conflits
Identifier les conflits
# Vérifier les conflits avant la 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
# Voir les marqueurs de conflit dans le fichier
# <<<<<<< HEAD
# contenu de main
# =======
# contenu de la branche de fonctionnalité
# >>>>>>> feature/user-auth
# Option 1 : Résolution manuelle
# Modifier le fichier, supprimer les marqueurs, conserver 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 de main
git checkout --theirs src/auth/login.ts # Garder la version de la fonctionnalité
# 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 concernant les fichiers partagés
# 4. Utiliser des feature flags plutôt que des branches de longue durée
# 5. Réviser et fusionner les PR rapidement
Gestion des branches
Conventions de nommage
# Branches de fonctionnalités
feature/user-authentication
feature/JIRA-123-payment-integration
# Corrections de bugs
fix/login-redirect-loop
fix/456-null-pointer-exception
# Correctifs (problèmes de production)
hotfix/critical-security-patch
hotfix/database-connection-leak
# Publications
release/1.2.0
release/2024-01-hotfix
# Expériences/POC
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 à distance 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 # Suppression forcée
# Supprimer une branche distante
git push origin --delete feature/user-auth
Workflow de stash
# Sauvegarder le travail en cours
git stash push -m "WIP: authentification utilisateur"
# Lister les stashs
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 versions
Gestion sémantique de version
MAJEUR.MINEUR.CORRECTIF
MAJEUR : Modifications cassantes
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 : modification cassante)
Créer des versions
# Créer un tag annoté
git tag -a v1.2.0 -m "Version v1.2.0
Fonctionnalités :
- Ajouter l'authentification utilisateur
- Implémenter la réinitialisation du mot de passe
Corrections :
- Résoudre le problème de redirection de connexion
Modifications cassantes :
- Aucune"
# 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 un 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é 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 (rebaser au lieu de fusionner)
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 en 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
# Journaux
*.log
logs/
# Couverture de test
coverage/
# Cache
.cache/
*.tsbuildinfo
Workflows courants
Démarrer 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. Apporter des modifications et valider
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
Mettre à jour une PR avec de nouvelles modifications
# 1. Apporter 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
Synchroniser un fork avec le dépôt amont
# 1. Ajouter le dépôt amont (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
Annuler des erreurs
# Annuler le dernier commit (conserver les modifications)
git reset --soft HEAD~1
# Annuler le dernier commit (supprimer 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-oublié
git commit --amend --no-edit
Hooks Git
Hook Pre-Commit
#!/bin/bash
# .git/hooks/pre-commit
# Exécuter le lint
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 potentiel détecté. Validation annulée."
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 les instructions 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-patrons
# MAUVAIS : Valider directement sur main
git checkout main
git commit -m "corriger bug"
# BON : Utiliser des branches de fonctionnalités et des PR
# MAUVAIS : Valider des secrets
git add .env # Contient des clés API
# BON : Ajouter à .gitignore, utiliser des variables d'environnement
# MAUVAIS : PR géantes (1000+ lignes)
# BON : Diviser en PR 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éécrire 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 : Commits volumineux mélangeant des changements non liés
git add .
git commit -m "diverses modifications"
# BON : Commits atomiques avec un objectif unique
# MAUVAIS : Ignorer les échecs IC
git commit --allow-failure
# BON : L'IC doit toujours passer avant la fusion
Résumé des workflows Git
| Workflow | Quand l'utiliser | Commande clé |
|---|---|---|
| Créer une fonctionnalité | Début du travail sur une fonctionnalité | git checkout -b feature/nom |
| Mettre à jour la branche | Avant PR | git rebase origin/main |
| Valider des modifications | Modifications atomiques | git commit -m "type(portée): message" |
| Pousser des modifications | Partager le travail | git push -u origin feature/nom |
| Créer une PR | Révision et fusion | Interface GitHub/GitLab |
| Fusionner une PR | Terminer une fonctionnalité | git merge feature/nom (ou bouton sur l'interface) |
| Créer une version | Marquer un jalon | git tag -a v1.0.0 -m "message" |
| Annuler un commit | Corriger une erreur | git revert HEAD |
| Stasher du travail | Changer de contexte | git stash push -m "message" |