Gestion des branches
Introduction
Quand on travaille sur un projet, on veut souvent développer une nouvelle fonctionnalité ou corriger un bug sans risquer de casser le code qui fonctionne déjà. C'est exactement le rôle des branches dans Git.
Objectifs de ce cours :
- Comprendre ce qu'est une branche Git et pourquoi les utiliser
- Créer et naviguer entre les branches avec
git branchetgit switch - Fusionner des branches avec
git merge - Résoudre les conflits de fusion
1. Qu'est-ce qu'une Branche?
Concept
Une branche est une ligne de développement indépendante. Elle permet de travailler sur des modifications sans affecter la branche principale (main).
Analogie
Imaginez un livre dont vous écrivez la suite. La branche main est le manuscrit officiel. Quand vous voulez essayer un nouveau chapitre, vous faites une photocopie et travaillez dessus. Si le chapitre est bon, vous l'intégrez dans le manuscrit. Sinon, vous jetez la photocopie sans avoir abîmé l'original.
Visualisation
A---B---C (fonctionnalite-login)
/
main: D---E---F---G
\
H---I (fix-bug-42)
Chaque lettre est un commit. On voit trois branches : main, fonctionnalite-login et fix-bug-42, qui évoluent en parallèle.
2. Commandes de Base pour les Branches
Lister les branches
git branch
La branche courante est marquée d'un * :
fix-bug-42
fonctionnalite-login
* main
Créer une branche
git branch nom-de-la-branche
Cela crée la branche mais ne bascule pas dessus.
Supprimer une branche
# Supprimer une branche déjà fusionnée
git branch -d nom-de-la-branche
# Forcer la suppression (même si pas fusionnée)
git branch -D nom-de-la-branche
3. Naviguer entre les Branches avec git switch
Pourquoi git switch plutôt que git checkout?
La commande git checkout fait trop de choses différentes (changer de branche, restaurer des fichiers, etc.). Git a introduit git switch pour clarifier l'intention : changer de branche.
Changer de branche
git switch nom-de-la-branche
Exemple :
git switch fonctionnalite-login
Git met à jour les fichiers dans votre répertoire de travail pour refléter l'état de cette branche.
Créer et basculer en une seule commande
git switch -c nouvelle-branche
C'est l'équivalent de :
git branch nouvelle-branche
git switch nouvelle-branche
Revenir à la branche précédente
git switch -
Exemple complet
# On est sur main
git switch -c ajout-validation
# On fait nos modifications
git add .
git commit -m "Ajouter validation du courriel"
# On revient sur main
git switch main
IMPORTANT : Avant de changer de branche, assurez-vous que vos modifications sont commitées ou mises de côté (git stash). Sinon, Git refusera le changement si des conflits sont possibles.
4. Fusionner des Branches avec git merge
Concept
Le merge (fusion) intègre les modifications d'une branche dans une autre. Typiquement, on fusionne une branche de fonctionnalité dans main quand le travail est terminé.
Workflow typique
# 1. Se placer sur la branche qui REÇOIT les modifications
git switch main
# 2. Fusionner la branche source
git merge ajout-validation
Après le merge, les commits de ajout-validation sont intégrés dans main.
Visualisation d'un merge
Avant :
A---B---C (ajout-validation)
/
main: D---E
Après git merge ajout-validation (depuis main) :
A---B---C (ajout-validation)
/ \
main: D---E---------M (M = commit de merge)
Fast-Forward Merge
Si main n'a eu aucun nouveau commit depuis la création de la branche, Git fait un fast-forward : il avance simplement le pointeur de main.
Avant :
main: D---E
\
A---B---C (ajout-validation)
Après fast-forward merge :
main: D---E---A---B---C
Pas de commit de merge supplémentaire. L'historique reste linéaire.
5. Résoudre les Conflits de Fusion
Quand un conflit survient-il?
Un conflit arrive quand les deux branches ont modifié la même partie du même fichier. Git ne peut pas décider automatiquement quelle version garder.
Exemple de conflit
Sur main, le fichier Utilisateur.java contient :
public String getNom() {
return nom;
}
Sur la branche validation, on a changé pour :
public String getNom() {
return nom.trim();
}
Sur main, quelqu'un d'autre a changé pour :
public String getNom() {
return nom.toUpperCase();
}
Ce que Git affiche
Quand on fait git merge validation depuis main :
Auto-merging Utilisateur.java
CONFLICT (content): Merge conflict in Utilisateur.java
Automatic merge failed; fix conflicts and then commit the result.
Le fichier contient maintenant des marqueurs de conflit :
public String getNom() {
<<<<<<< HEAD
return nom.toUpperCase();
=======
return nom.trim();
>>>>>>> validation
}
<<<<<<< HEAD: Version de la branche courante (main)=======: Séparateur>>>>>>> validation: Version de la branche qu'on fusionne
Résoudre le conflit
- Ouvrir le fichier et choisir la bonne version (ou combiner les deux)
- Supprimer les marqueurs de conflit
- Commiter le résultat
// Résolution : on combine les deux
public String getNom() {
return nom.trim().toUpperCase();
}
git add Utilisateur.java
git commit -m "Résoudre conflit: combiner trim et toUpperCase dans getNom"
Résolution dans IntelliJ / VS Code
Les IDE modernes offrent une interface visuelle pour résoudre les conflits. Ils affichent les deux versions côte à côte et permettent de choisir ou combiner les changements.
Dans IntelliJ :
- Cliquer sur "Resolve Conflicts" dans la notification
- Choisir "Accept Yours", "Accept Theirs" ou "Merge" pour chaque conflit
6. Convention de Nommage des Branches
Donner un nom clair à ses branches facilite la collaboration.
Conventions courantes :
| Préfixe | Usage | Exemple |
|---|---|---|
feature/ | Nouvelle fonctionnalité | feature/ajout-login |
fix/ | Correction de bug | fix/null-pointer-email |
refactor/ | Refactoring | refactor/extraction-methode |
test/ | Ajout de tests | test/couverture-utilisateur |
BON :
git switch -c feature/ajout-validation-courriel
git switch -c fix/crash-liste-vide
MAUVAIS :
git switch -c ma-branche
git switch -c test123
git switch -c aaa
7. Workflow Complet : Exemple Pratique
Voici un exemple de bout en bout pour ajouter une fonctionnalité dans un projet.
# 1. S'assurer d'être à jour sur main
git switch main
git pull
# 2. Créer une branche pour la fonctionnalité
git switch -c feature/ajout-age-utilisateur
# 3. Faire les modifications dans le code
# ... modifier Utilisateur.java ...
# 4. Vérifier les changements
git status
git diff
# 5. Commiter
git add Utilisateur.java
git commit -m "Ajouter méthode getAge dans Utilisateur"
# 6. Revenir sur main et fusionner
git switch main
git merge feature/ajout-age-utilisateur
# 7. Supprimer la branche (elle a été fusionnée)
git branch -d feature/ajout-age-utilisateur
# 8. Pousser main
git push
8. Pousser et Supprimer une Branche sur le Dépôt Distant
Pousser une branche absente sur origin
Quand on crée une branche localement avec git switch -c, elle n'existe pas encore sur le dépôt distant. La première fois qu'on veut la pousser, Git ne sait pas vers quelle branche distante envoyer les commits. Il faut lui indiquer explicitement avec --set-upstream (ou -u) :
git push -u origin nom-de-la-branche
L'option -u associe la branche locale à la branche distante. Les fois suivantes, un simple git push suffit.
Exemple :
git switch -c feature/ajout-recherche
# ... commits ...
# Première poussée : la branche n'existe pas encore sur origin
git push -u origin feature/ajout-recherche
Git confirme la création de la branche distante :
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:utilisateur/projet.git
* [new branch] feature/ajout-recherche -> feature/ajout-recherche
Branch 'feature/ajout-recherche' set up to track remote branch 'feature/ajout-recherche' from 'origin'.
Supprimer une branche sur origin
Une fois une branche fusionnée (via un merge ou une pull request), il est bon de la supprimer également sur le dépôt distant pour garder le projet propre.
git push origin --delete nom-de-la-branche
Exemple :
git push origin --delete feature/ajout-recherche
Git confirme la suppression :
To github.com:utilisateur/projet.git
- [deleted] feature/ajout-recherche
Supprimer la branche distante n'affecte pas la branche locale. Pour supprimer les deux, il faut aussi faire git branch -d nom-de-la-branche.
Voir les branches distantes
# Lister les branches distantes
git branch -r
# Lister toutes les branches (locales et distantes)
git branch -a
9. Bonnes Pratiques
BON
- Une branche par tâche : Ne pas mélanger plusieurs fonctionnalités dans une branche
- Noms descriptifs : Le nom de la branche doit indiquer ce qu'on y fait
- Commits réguliers : Commiter souvent avec des messages clairs
- Fusionner souvent : Ne pas laisser une branche diverger trop longtemps de
main - Supprimer après fusion : Nettoyer les branches qui ne servent plus
MAUVAIS
- Travailler directement sur
main: Toujours créer une branche - Branches géantes : Une branche qui vit des semaines avec des centaines de modifications
- Noms vagues :
test,temp,ma-branche - Accumuler les branches mortes : Supprimer les branches fusionnées
10. Résumé des Commandes
| Commande | Description |
|---|---|
git branch | Lister les branches locales |
git branch -r | Lister les branches distantes |
git branch -a | Lister toutes les branches |
git branch nom | Créer une branche |
git branch -d nom | Supprimer une branche fusionnée |
git branch -D nom | Forcer la suppression d'une branche |
git switch nom | Basculer sur une branche |
git switch -c nom | Créer et basculer sur une branche |
git switch - | Revenir à la branche précédente |
git merge nom | Fusionner une branche dans la branche courante |
git push -u origin nom | Pousser une nouvelle branche sur origin |
git push origin --delete nom | Supprimer une branche sur origin |
Ressources
- Guide GitHub: https://docs.github.com/en/pull-requests
- First Timers Only: https://www.firsttimersonly.com/
- Good First Issue: https://goodfirstissue.dev/
- Up For Grabs: https://up-for-grabs.net/