git merge

Branches et fusions

Réunir deux historiques de développement ou plus


La commande 'git merge' intègre dans la branche courante les modifications des commits nommés (depuis le moment où leurs historiques ont divergé de la branche courante). Git fait une fusion « fast-forward » quand c’est possible (quand la branche courante est un ancêtre de la branche fusionnée), ou crée un « commit de fusion » quand les historiques ont divergé. En cas de conflits entre les branches, Git s’arrête et vous demande de les résoudre avant de terminer la fusion.

Synopsis

git merge [--no-ff | --ff-only] [--squash] [--no-commit] [-m <msg>] [--allow-unrelated-histories] [<commit>...]
git merge (--continue | --abort | --quit)
[ ] facultatif| ou<arg> valeur à remplacer... répétable--flag option

Options

Cliquez sur une option pour la déplier

Débutant (5)

Créer un commit de fusion même quand la fusion pourrait se faire en fast-forward. Préserve l’historique de la branche et montre clairement où le travail sur la fonctionnalité a commencé et fini.

Si nécessaireEnregistre toujours un commit de fusion — un choix de convention d’équipe

Exemple

git merge --no-ff feature

Refuser de fusionner sauf si le HEAD courant est déjà à jour ou si la fusion peut se faire en fast-forward. Évite les commits de fusion accidentels.

RecommandéNe crée jamais de commit de fusion surprise ; échoue si les historiques ont divergé

Exemple

git merge --ff-only feature

Abandonner la résolution de conflit en cours et remettre le dépôt dans son état d’avant la fusion. À utiliser pour annuler une fusion en conflit.

RecommandéSort sans risque d’une fusion en conflit et revient à l’état d’avant

Exemple

git merge --abort

Après avoir résolu les conflits, conclure la fusion. Équivaut à lancer git commit après la résolution des conflits.

RecommandéTermine la fusion après avoir résolu et préparé les conflits

Exemple

git merge --continue

Définir un message personnalisé pour le commit de fusion. N’impose pas de commit de fusion : en fast-forward, le message est ignoré (combinez avec --no-ff pour toujours en avoir un).

Si nécessaireMessage de commit de fusion personnalisé ; ignoré en cas de fast-forward

Exemple

git merge -m "Integrate login feature" feature

Intermédiaire (2)

Regrouper tous les commits de la branche fusionnée en un seul ensemble de modifications indexées. Ne crée pas de commit et n’enregistre pas de fusion (pas de MERGE_HEAD) - vous committez à la main, et le résultat est un commit normal à un seul parent.

Si nécessaireUn commit propre, mais pas une vraie fusion ; la branche demande ensuite -D

Exemple

git merge --squash feature

Faire la fusion mais s’arrêter avant de créer un commit. Permet d’examiner et de modifier le résultat avant de committer. Un fast-forward a quand même lieu ; ajoutez --no-ff pour garantir l’arrêt.

Si nécessaireInspectez le résultat avant de committer ; à associer à --no-ff

Exemple

git merge --no-commit feature

Avancé (1)

Autoriser la fusion d’historiques sans ancêtre commun. Utile pour réunir deux dépôts ou projets séparés.

Si nécessaireSeulement pour réunir volontairement des projets séparés

Exemple

git merge --allow-unrelated-histories other-project/main

Choisir la bonne option

Stratégies de fusion

Comment contrôler le type de fusion que fait Git

CommandeCrée un commit de fusionPréserve l’historiqueIdéal pour
git merge (default)En cas de divergenceOuiIntégration normale d’une fonctionnalité
git merge --no-ffToujoursOuiDocumenter les fusions de fonctionnalités
git merge --ff-onlyJamaisLinéaire seulementImposer un historique propre
git merge --squashNon (commit normal)Non (aplati)Branche main propre

Gérer les conflits

Que faire quand une fusion a des conflits

CommandeActionGarde le travailQuand l’utiliser
(resolve manually)Modifier les fichiers, git addOuiBesoin de parties des deux côtés
--continueTerminer la fusionOuiAprès avoir résolu les conflits
--abortAnnuler la fusionÉtat d’avant la fusionPas prêt à résoudre maintenant
checkout --ours/--theirsChoisir un côtéUne seule versionUn côté est clairement le bon

merge ou rebase

Deux façons d’intégrer des modifications - des compromis différents

CommandeHistoriqueRésolution des conflitsIdéal pour
git mergePréserve tous les commitsUne foisBranches partagées, PR
git rebaseRéécrit en linéairePar commitNettoyage local, branches privées
git merge --squashUn seul commitUne foisFonctionnalité à l’historique désordonné

Contrôler le commit

Options pour personnaliser le commit de fusion

CommandeCommitte automatiquementCas d’usage
git merge featureOui (sans conflit)Fusion standard
git merge --no-commitNon (indexé)Relire avant le commit
git merge -m "msg"Oui (ignoré en fast-forward)Commits de fusion descriptifs
git merge --squashNon (commit obligatoire)Regrouper tous les commits en un seul

Exemples de workflows

1
git checkout main

Passer sur la branche main

2
git pull origin main

Récupérer les dernières modifications du dépôt distant

3
git merge --no-ff feature-branch

Fusionner la fonctionnalité avec un commit de fusion pour l’historique

4
git push origin main

Pousser les modifications fusionnées vers le dépôt distant

5
git branch -d feature-branch

Supprimer la branche de fonctionnalité fusionnée

1
git merge feature

Tenter la fusion (des conflits apparaissent)

2
git status

Voir quels fichiers sont en conflit

3
(edit conflicted files)

Chercher les marqueurs <<<<<<< et résoudre à la main

4
git add <resolved-files>

Indexer les fichiers résolus

5
git merge --continue

Terminer la fusion avec un commit

1
git checkout main

Passer sur la branche main

2
git merge --squash feature-branch

Regrouper tous les commits en modifications indexées

3
git commit -m "Add feature X"

Créer un seul commit propre avec toutes les modifications

4
git branch -D feature-branch

Forcer la suppression de la branche de fonctionnalité

1
git merge feature

Lancer la fusion (des problèmes surviennent)

2
git status

Voir l’état en conflit

3
git merge --abort

Annuler et revenir à l’état d’avant la fusion

4
git status

Vérifier que vous êtes revenu à un état propre

Dépannage

CONFLICT (content): Merge conflict in file.js

Cause : Les deux branches ont modifié les mêmes lignes du fichier

Ouvrez le fichier, cherchez les marqueurs <<<<<<<, corrigez, puis git add et git merge --continue

fatal: refusing to merge unrelated histories

Cause : Les branches n’ont aucun ancêtre commun (dépôts séparés)

Utilisez git merge --allow-unrelated-histories si vous voulez vraiment réunir des projets séparés

Already up to date

Cause : La branche que vous fusionnez est déjà incluse dans votre branche courante

Rien à faire - votre branche contient déjà tous les commits de la cible

error: Your local changes to the following files would be overwritten by merge

Cause : Vous avez des modifications non committées qui entrent en conflit avec la fusion

Committez vos modifications, mettez-les dans le stash (git stash), ou jetez-les avant de fusionner

La fusion est faite mais je voulais d’abord relire

Cause : Git a committé la fusion automatiquement

La prochaine fois, utilisez --no-ff --no-commit. Pour recommencer : git reset --merge ORIG_HEAD, puis refaites la fusion avec --no-commit

Astuces et pièges

Bonnes pratiques

  • ✓Faites toujours un pull des dernières modifications avant de fusionner pour limiter les conflits
  • ✓Utilisez --no-ff pour les branches de fonctionnalité afin de garder le contexte de la fusion dans l’historique
  • ✓Écrivez des messages de fusion descriptifs qui expliquent ce qui a été intégré
  • ✓Supprimez les branches de fonctionnalité après la fusion pour garder le dépôt propre
  • ✓Testez votre code après la fusion et avant de pousser, pour vérifier que rien n’est cassé
  • ✓Utilisez git merge --abort si vous n’êtes pas prêt à résoudre les conflits - ne laissez pas une fusion à moitié faite
  • ✓Pour les branches de longue durée, fusionnez régulièrement main dans votre branche de fonctionnalité pour réduire les conflits de la fusion finale

Erreurs fréquentes

  • ✗Fusionner sans avoir d’abord récupéré les dernières modifications du dépôt distant. Faites toujours 'git pull' avant de fusionner pour éviter les conflits.
  • ✗Indexer des fichiers qui contiennent encore des marqueurs de conflit. Git bloque les commits tant que des chemins ne sont pas fusionnés, mais dès que vous faites 'git add' sur un fichier, il committe les marqueurs <<<<<<< tels quels.
  • ✗Utiliser des fusions fast-forward pour les branches de fonctionnalité fait perdre l’historique de la branche. Utilisez '--no-ff' pour garder le contexte.
  • ✗Lancer 'git merge --abort' après avoir résolu les conflits à la main fait perdre tout ce travail de résolution.
  • ✗Fusionner dans la mauvaise branche. Vérifiez toujours avec 'git branch' que vous êtes sur la bonne branche cible avant de fusionner.

FAQ

A:

Merge préserve l’historique et crée un commit de fusion. Rebase réécrit l’historique pour le rendre linéaire. Utilisez merge pour les branches partagées, rebase pour le nettoyage local.

A:

Utilisez --no-ff pour fusionner les branches de fonctionnalité dans main. Il crée un commit de fusion qui date l’intégration de la fonctionnalité, même si un fast-forward était possible.

A:

Si elle n’est pas poussée : git reset --hard ORIG_HEAD (fonctionne aussi pour les fast-forwards ; jette les modifications non committées). Si elle est poussée : git revert -m 1 <merge-commit> pour créer un nouveau commit qui annule la fusion.

A:

Un fast-forward a lieu quand votre branche n’a aucun nouveau commit depuis le point de bifurcation. Git avance simplement le pointeur au lieu de créer un commit de fusion.

A:

Ouvrez les fichiers en conflit, cherchez les marqueurs <<<<<<<, gardez le code voulu, retirez les marqueurs, puis faites git add sur les fichiers et git merge --continue.

A:

Une fusion normale préserve tout l’historique des commits. Une fusion squash regroupe tout en un seul commit. Utilisez squash quand la branche de fonctionnalité a des commits WIP désordonnés que vous ne voulez pas dans main.