Ce que vous saurez faire à la fin
- Adopter trunk-based workflow en équipe
- Utiliser PRs et code review efficacement
- Automatiser avec husky + commitlint
- Protéger main correctement
- Releases avec changelog automatique
Étape 1 — Workflow trunk-based
git switch main
git pull --rebase
git switch -c feat/export-pdf
# Dev + commits atomiques
git add src/pdf.ts
git commit -m "feat(pdf): export facture PDF"
git push -u origin feat/export-pdf
gh pr create --fill --base main
Étape 2 — Conventional commits
feat: nouveauté
fix: correctif
docs: doc
refactor: refactor
test: tests
chore: maintenance
perf: performance
feat(auth): login OAuth Google
fix(billing): arrondit TVA au FCFA supérieur
BREAKING CHANGE: renomme /v1/ en /v2/
Étape 3 — Template PR
<!-- .github/pull_request_template.md -->
## Contexte
Closes #
## Changements
-
## Tests
- [ ] Unitaires
- [ ] Testé local
## Rollback
<!-- comment revenir en arrière -->
Étape 4 — Protection de main
gh api -X PUT repos/ORG/REPO/branches/main/protection \
-F required_status_checks='{"strict":true,"contexts":["test"]}' \
-F required_pull_request_reviews='{"required_approving_review_count":1}' \
-F enforce_admins=true
Étape 5 — CODEOWNERS
# .github/CODEOWNERS
* @org/core
/src/billing/ @org/billing
/infra/ @org/sre
*.sql @aminata-diop
Étape 6 — Husky + commitlint
npm install -D husky @commitlint/cli @commitlint/config-conventional lint-staged
npx husky init
echo "npx --no -- commitlint --edit $1" > .husky/commit-msg
echo "npx lint-staged" > .husky/pre-commit
// commitlint.config.js
export default { extends: ["@commitlint/config-conventional"] };
Étape 7 — Code review
gh pr checkout 142
gh pr diff 142 | less
gh pr review 142 --approve --body "LGTM"
gh pr review 142 --request-changes --body "Ajouter tests edge case"
# Merger
gh pr merge 142 --squash --delete-branch
Règles d’équipe : PR ≤ 400 lignes, retour sous 24h, résoudre tous les fils avant merge.
Étape 8 — Résoudre conflits avec rebase
git fetch origin main
git rebase origin/main
# Si conflit:
git status
# éditer fichiers
git add fichier-resolu.js
git rebase --continue
git push --force-with-lease
Étape 9 — Changelog automatique
npm install -D conventional-changelog-cli
npx conventional-changelog -p angular -i CHANGELOG.md -s
git add CHANGELOG.md
git commit -m "chore(release): 1.3.0"
git tag v1.3.0
git push --tags
Étape 10 — Semantic-release en CI
name: Release
on:
push:
branches: [main]
permissions: { contents: write }
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: actions/setup-node@v4
- run: npm ci
- run: npx semantic-release
env: { GITHUB_TOKEN: ${{ github.token }} }
Checklist équipe
✓ Branch protection sur main
✓ CODEOWNERS défini
✓ Template PR
✓ husky + commitlint
✓ lint-staged auto-format
✓ Squash merge
✓ Tags sémantiques
✓ Changelog auto
✓ Review sous 24h
Pourquoi formaliser un workflow Git en équipe à Dakar, Abidjan ou Cotonou
Quand une équipe de trois à dix développeurs partage un dépôt depuis Dakar, Abidjan, Cotonou ou Lomé, l’absence de workflow formel finit toujours par coûter des heures de débogage et des conflits de merge évitables. Ce guide pose un workflow Git robuste applicable à un projet Laravel, Node.js ou Django hébergé sur un VPS Hetzner ou Contabo facturé en euros (1 EUR = 655,957 FCFA). L’objectif : un dépôt principal stable, des branches courtes, des revues systématiques.
Avant de plonger dans les commandes, sachez que ce tutoriel suppose Git 2.43+ installé localement et un compte GitHub ou GitLab actif. Vérifiez votre version avec git --version ; si la sortie affiche 2.30 ou inférieur, mettez à jour avant de continuer car certaines commandes (git switch, git restore) seront indisponibles.
Étape 1 — Choisir un modèle : trunk-based ou GitHub Flow
Pour une équipe ouest-africaine de moins de dix devs, le GitHub Flow simplifié bat GitFlow en lisibilité. Une seule branche longue (main), des branches éphémères feature/... mergées par Pull Request. GitFlow avec ses develop, release, hotfix est rarement justifié hors contexte SaaS multi-versions.
git switch main
git pull --ff-only origin main
git switch -c feature/paiement-wave
La sortie attendue est silencieuse sauf la dernière ligne : Switched to a new branch 'feature/paiement-wave'. Si git pull --ff-only échoue avec Not possible to fast-forward, votre main local diverge — rebasez ou réinitialisez avant de créer la feature branch.
Étape 2 — Convention de nommage des branches
Imposez un préfixe : feature/, fix/, chore/, docs/. Suffixe : verbe-court ou ticket. Exemples valides : feature/paiement-orange-money, fix/login-mixx-yas, chore/upgrade-node-22. Cette convention rend les filtres GitHub triviaux et permet aux hooks CI de cibler des patterns.
Étape 3 — Configurer Git localement pour éviter les pièges
Trois réglages économisent des heures sur l’année : pull en rebase par défaut, push de la branche courante uniquement, line-endings cohérents pour les équipes mixtes Windows/Linux.
git config --global pull.rebase true
git config --global push.default current
git config --global core.autocrlf input
Sur une machine Windows d’un développeur basé à Abidjan, remplacez input par true. Vérifiez ensuite avec git config --global --list | grep -E 'pull|push|core' : trois lignes doivent apparaître.
Étape 4 — Pull Request, revue et merge propre
Avant de pousser une feature branch, rebasez-la sur main à jour pour éviter un merge commit parasite. La séquence standard tient en quatre commandes.
git switch feature/paiement-wave
git fetch origin
git rebase origin/main
git push --force-with-lease
Le drapeau --force-with-lease protège contre l’écrasement involontaire du travail d’un coéquipier : si quelqu’un d’autre a poussé entre-temps, le push sera refusé. C’est l’alternative sûre à --force brut. Une fois la PR approuvée par au moins un reviewer, mergez via l’interface GitHub en mode Squash and merge pour garder un historique linéaire sur main.
Étape 5 — Résoudre un conflit sans paniquer
Un conflit lors d’un rebase n’est pas un drame. Git s’arrête, marque les fichiers en conflit, et attend votre arbitrage. Identifiez les fichiers, éditez-les, marquez-les résolus, puis continuez.
git status
# édition manuelle des sections <<<<<<<
git add fichier-en-conflit.php
git rebase --continue
Si le rebase devient ingérable (plus de cinq fichiers en conflit), abandonnez avec git rebase --abort et privilégiez un git merge origin/main classique : moins élégant mais souvent plus rapide à débloquer.
Étape 6 — Hooks pre-commit pour bloquer les bêtises
Un hook pre-commit évite de pousser des secrets, des console.log oubliés ou un fichier .env. Installez pre-commit et configurez un .pre-commit-config.yaml minimal.
pip install pre-commit
pre-commit install
Après installation, chaque git commit déclenche les hooks. Si l’un échoue, le commit est annulé et le code reste à corriger. Vous pouvez exiger le passage des linters ESLint, Prettier, PHPStan ou Ruff selon le stack de l’équipe.
Étape 7 — Stratégie de tags et de releases
Étiquetez chaque mise en production avec un tag SemVer signé : git tag -a v1.4.0 -m "Release 1.4.0 — paiement Wave". Poussez avec git push origin v1.4.0. Sur GitHub, créez ensuite une Release attachée à ce tag avec un changelog généré depuis les commits. Cette traçabilité est précieuse pour rollback rapide en cas d’incident en production.
Étape 8 — Récupérer un travail perdu avec reflog
Un git reset --hard malheureux ou une branche supprimée par erreur ne sont pas définitifs pendant 90 jours. git reflog affiche tous les déplacements de HEAD ; retrouvez le SHA voulu et restaurez avec git checkout -b sauvetage <sha>. Cette commande a sauvé plus d’une journée de travail à des équipes pressées.
Étape 9 — Documenter le workflow dans le dépôt
Créez un fichier CONTRIBUTING.md à la racine décrivant le workflow choisi, les conventions de nommage, le processus de revue, les responsables par module. Dans la continuité sur la culture DevOps, consultez notre guide DevOps essentiels pour équipes et nos bonnes pratiques de sécurité VPS.
Étape 10 — Mettre en place un cache Git LFS pour les assets lourds
Les projets web ouest-africains accumulent souvent des PSD, des PDF de plaquette, des vidéos de démo de plusieurs centaines de mégaoctets. Stocker ces fichiers directement dans Git ralentit chaque clone et fait exploser le quota du dépôt. Git LFS (Large File Storage) déporte ces blobs hors du dépôt principal et ne télécharge qu’à la demande.
git lfs install
git lfs track "*.psd" "*.mp4" "*.zip"
git add .gitattributes
git commit -m "chore: activer Git LFS pour assets lourds"
Le fichier .gitattributes généré liste les patterns suivis par LFS. Vérifiez avec git lfs ls-files après le premier commit incluant un asset ; chaque fichier suivi doit apparaître avec son hash. Sur GitHub gratuit, le quota LFS est de 1 Go de stockage et 1 Go de bande passante par mois, ce qui couvre la plupart des projets de TPE locales. Au-delà, GitLab self-hosted sur votre VPS Hetzner reste l’option la plus économique : pas de plafond LFS hors disque réel.
Étape 11 — Protéger main avec des règles serveur
Côté serveur, activez la protection de branche sur main dans GitHub Settings → Branches → Add rule. Cochez : Require a pull request before merging, Require approvals (1), Require status checks to pass, Require linear history, Do not allow bypassing the above settings. Cette configuration empêche un push direct accidentel sur main, même par un admin pressé un vendredi soir.
Si vous utilisez GitLab self-hosted, l’équivalent se trouve dans Settings → Repository → Protected branches. Choisissez Maintainers pour Allowed to merge et No one pour Allowed to push and merge. Toute MR devra passer par l’interface, ce qui force la revue.
Étape 12 — Intégration continue minimale GitHub Actions
Un workflow CI minimal exécute les tests à chaque PR et bloque le merge si rouge. Créez .github/workflows/ci.yml avec un job qui installe les dépendances, lance les tests, et publie le résultat. Pour un projet Node.js typique :
name: CI
on: [pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- run: npm ci
- run: npm test
Au premier push, GitHub Actions exécute le workflow. L’onglet Actions affiche le déroulement en temps réel. Si un test échoue, la PR est marquée rouge et le bouton Merge reste grisé tant que la branche de protection est active. Les minutes Actions sont gratuites jusqu’à 2000 par mois sur les dépôts privés du plan Free, largement suffisant pour une équipe de cinq devs.
Étape 13 — Nettoyer les branches mergées chaque semaine
Au bout de quelques mois, le dépôt accumule des dizaines de branches obsolètes. Listez-les avec git branch --merged main côté local et supprimez-les en lot : git branch --merged main | grep -v '^\*\| main$' | xargs -n 1 git branch -d. Côté distant, GitHub propose Automatically delete head branches dans Settings → General → Pull Requests : cochez cette option pour que chaque branche soit supprimée automatiquement après merge de sa PR. Combiné à un nettoyage local hebdomadaire, le dépôt reste lisible.
Étape 14 — Sauvegarde et miroir du dépôt
Un dépôt critique mérite un miroir hors GitHub. Configurez un remote secondaire sur votre VPS Hetzner ou Contabo avec git remote add backup git@vps.exemple.io:projets/api.git, puis poussez régulièrement avec git push --mirror backup. Un cron quotidien sur la machine d’un lead suffit. Coût d’un VPS minimal : environ 5 EUR par mois soit 3280 FCFA, négligeable pour la tranquillité d’esprit.
Étape 15 — Conventions de messages de commit
Adopter le standard Conventional Commits transforme l’historique en source d’information exploitable. Chaque commit commence par un type (feat, fix, docs, refactor, test, chore) suivi d’un scope optionnel et d’une description impérative courte. Exemples concrets : feat(paiement): integrer Wave Senegal, fix(auth): corriger expiration JWT mobile, docs(readme): ajouter prerequis Node 22. Cette discipline permet de générer un changelog automatique avec un outil comme git-cliff ou standard-version, et facilite les revues : un reviewer comprend l’intention sans ouvrir le diff.
Pour faire respecter le format, ajoutez le hook commitlint via npm install --save-dev @commitlint/cli @commitlint/config-conventional et configurez-le dans commitlint.config.js. Combiné à husky, chaque commit non conforme est rejeté avant même d’arriver dans l’historique. Une équipe de cinq devs adopte cette habitude en deux semaines, et l’historique devient drastiquement plus lisible.
Étape 16 — Cherry-pick ciblé vers une branche de release
Quand main contient déjà la fonctionnalité v2 mais qu’un correctif urgent doit partir en production sur la v1, le cherry-pick devient indispensable. Identifiez le SHA du correctif sur main avec git log --oneline, basculez sur la branche de release : git switch release/v1.x, puis appliquez le commit ciblé : git cherry-pick a3f9c2d. Si le commit s’applique proprement, le tour est joué ; sinon Git signale les conflits comme pour un rebase. Cette approche évite de merger toute la branche main dans la release et de tirer accidentellement des features non testées en production.
Étape 17 — Bisect pour localiser un bug introduit
Un bug est apparu mais personne ne sait quel commit l’a introduit ? git bisect trouve le coupable en quelques minutes par dichotomie. Lancez git bisect start, marquez le commit actuel comme cassé : git bisect bad, puis indiquez un commit ancien réputé sain : git bisect good v1.2.0. Git checkout un commit intermédiaire ; testez, puis répondez git bisect good ou git bisect bad. Après cinq à dix itérations sur un historique de mille commits, Git affiche le SHA exact responsable. Terminez avec git bisect reset pour revenir à la branche de départ.
Étape 18 — Onboarding d’un nouveau développeur
Documentez en une page dans CONTRIBUTING.md les six étapes d’onboarding : cloner le dépôt, copier .env.example vers .env, installer les dépendances, lancer les migrations, démarrer le serveur de dev, exécuter la suite de tests. Un nouveau développeur basé à Lomé ou Cotonou doit pouvoir lancer le projet en moins d’une heure sans solliciter le lead. Ajoutez un canal Slack ou WhatsApp dédié #dev-help pour questions rapides, et un calendrier de pair-programming hebdomadaire les deux premières semaines pour transmettre les conventions tacites du dépôt.