Branches et fusion

Branches et fusion

Pourquoi les branches ?

Les branches sont l'un des concepts les plus puissants de Git. Elles permettent de travailler sur différentes fonctionnalités en parallèle, sans interférer avec le code stable.

main        ●───●───●───────────●───●
                     \         /
feature/login         ●───●───●

Chaque branche est simplement un pointeur vers un commit. Créer une branche est quasi instantané.

Manipuler les branches

Créer et naviguer

# Voir les branches
git branch                       # Branches locales
git branch -a                    # Toutes (locales + distantes)

# Créer une branche
git branch feature/login

# Changer de branche
git checkout feature/login
# Ou (Git 2.23+)
git switch feature/login

# Créer ET changer en une seule commande
git checkout -b feature/login
# Ou
git switch -c feature/login

# Supprimer une branche
git branch -d feature/login      # Seulement si fusionnée
git branch -D feature/login      # Forcer la suppression

Conventions de nommage

feature/nom-de-la-fonctionnalite   # Nouvelle fonctionnalité
fix/description-du-bug             # Correction de bug
hotfix/correction-urgente          # Correction urgente en production
refactor/nom-du-refactoring        # Refactoring
docs/mise-a-jour-readme            # Documentation

La fusion (merge)

Merge classique

# Se placer sur la branche de destination
git checkout main

# Fusionner la branche feature
git merge feature/login

Cas 1 : Fast-forward

Si main n'a pas bougé depuis la création de la branche, Git avance simplement le pointeur :

Avant :
main     ●───●
              \
feature        ●───●───●

Après (fast-forward) :
main     ●───●───●───●───●
# Forcer un commit de merge (même en fast-forward)
git merge --no-ff feature/login

Cas 2 : Merge avec commit

Si main a évolué en parallèle, Git crée un commit de merge :

Avant :
main     ●───●───●───●
              \
feature        ●───●

Après :
main     ●───●───●───●───M
              \          /
feature        ●───●────

Résoudre les conflits

Un conflit survient quand deux branches modifient la même partie d'un fichier.

Anatomie d'un conflit

<<<<<<< HEAD
const titre = "Bienvenue";
=======
const titre = "Bonjour !";
>>>>>>> feature/login
  • Entre <<<<<<< HEAD et ======= : le code de la branche courante
  • Entre ======= et >>>>>>> feature/login : le code de la branche entrante

Résoudre un conflit

# 1. Git signale le conflit lors du merge
git merge feature/login
# CONFLICT (content): Merge conflict in src/app.js

# 2. Voir les fichiers en conflit
git status

# 3. Ouvrir le fichier et choisir la bonne version
# Supprimer les marqueurs <<<<<<<, =======, >>>>>>> et garder le bon code
const titre = "Bienvenue !";

# 4. Marquer comme résolu et committer
git add src/app.js
git commit -m "Fusionner feature/login : résoudre le conflit sur le titre"

Annuler un merge en cours

# Si le merge se passe mal, on peut annuler
git merge --abort

Rebase — réécrire l'historique

Le rebase est une alternative au merge qui produit un historique linéaire.

Merge vs Rebase

Merge :
main     ●───●───●───●───M
              \          /
feature        ●───●────

Rebase :
main     ●───●───●───●
                       \
feature (rebasée)       ●'──●'
# Se placer sur la branche feature
git checkout feature/login

# Rebaser sur main
git rebase main

# Puis merger (fast-forward)
git checkout main
git merge feature/login

Quand utiliser rebase vs merge ?

Situation Recommandation
Mettre à jour une branche feature avec les derniers changements de main git rebase main
Intégrer une feature terminée dans main git merge --no-ff feature
Branche partagée avec d'autres développeurs Ne jamais rebaser
Branche locale personnelle Rebase OK

Règle d'or : ne jamais rebaser une branche qui a été poussée et partagée avec d'autres.

Cherry-pick — prendre un commit spécifique

# Appliquer un commit spécifique d'une autre branche
git cherry-pick abc1234

# Cherry-pick sans committer immédiatement
git cherry-pick --no-commit abc1234

# Utile pour :
# - Appliquer un hotfix sur plusieurs branches
# - Récupérer un commit d'une branche abandonnée

Workflows courants

Git Flow

main        ●─────────────────●─────────────●
             \               / \           /
develop       ●───●───●───●────●───●───●──●
                   \     /          \   /
feature/a           ●───●            ● ●
                                    feature/b
  • main : code en production
  • develop : intégration des features
  • feature/* : développement de fonctionnalités
  • release/* : préparation d'une release
  • hotfix/* : corrections urgentes

GitHub Flow (plus simple)

main        ●───●───●───────●───●
                     \     /
feature/login         ●───●
                      ↑
                Pull Request + Review
  1. Créer une branche depuis main
  2. Faire des commits
  3. Ouvrir une Pull Request
  4. Revue de code
  5. Merger dans main

Bonnes pratiques

  1. Une branche par fonctionnalité — gardez les branches courtes et focalisées
  2. Mettez à jour régulièrement votre branche feature depuis main
  3. Résolvez les conflits tôt — plus vous attendez, plus c'est compliqué
  4. Supprimez les branches fusionnées pour garder un dépôt propre
  5. Utilisez --no-ff pour les merges importants afin de conserver l'historique
  6. Ne forcez jamais un push sur main — utilisez des Pull Requests