Skip to content

Fusionner des fichiers

Fusion de fichier

Lorsque vous travaillez à plusieurs, il est fort probable que des modifications faites par d'autres contributeurs doivent être intégrés à votre copie locale. De même si vous travaillez sur plusieurs versions (branches) du contenu, vous aurez besoin d'intégrer les modifications d'une branche dans la version principale.

On parle de fusion de code, ou merge

Info

Git peut aussi utiliser la notion de réécriture d'historique des commit, ou rebase , pour certains de ces cas d'usage. Nous n'aborderons pas ces notions dans cette UE.

Dans la majeure partie des cas, la fusion se fait par Git automatiquement. Mais assez régulièrement, Git échouera à fusionner des fichiers, on parlera de conflits.

Les conflits arrivent donc en cas d'applications de modifications venant:

  • du serveur distant (via git pull)
  • d'une autre branche (via git merge)
  • de la récupération d'un brouillon (via git stash pop)

Exemple de conflit

Supposons un état initial (fichier local et distant) suivant pour le fichier README:

Notre projet ce nomme Foo

Un collaborateur corrige ce fichier comme suit:

Notre projet se nomme Foo

Pendant ce temps (donc avant d'avoir récupéré les modifications depuis le dépôt distant), vous modifiez le fichier comme suit:

Ce projet se nomme Foo

Vous faites commit puis push, mais Git rejette cette commande car votre dépôt local est en retard sur le dépôt distant. Vous faites donc pull pour récupérer les modifications. Le résultat est un fichier README en conflit dans lequel vous verrez:

<<<<<<< HEAD
Ce projet se nomme Foo
=======
Notre projet se nomme Foo
>>>>>>> main

Les symboles <<<<<<<, ======= et >>>>>>> (marqueurs de différence, voir utilitaire diff) délimitent les zones que Git n'a pas su fusionner, ainsi que les identifiants des branches impliquées.

Danger

Il ne faut jamais valider (commit) des changements contenant encore ces marqueurs de différence. Git ne peut empêcher automatiquement cela car dans certains cas (exemple: cette page web, hébergé sur Gitlab), la présence de ces marqueurs est voulue par l'auteur.

Résoudre les conflits

Pour résoudre un conflit dans un fichier, vous avez 3 possibilités:

  • si vous êtes certain que votre version est la seule à retenir

    git checkout --ours README
    

  • si vous êtes certain que la version du dépôt distant est la seule à retenir

    git checkout --theirs README
    

  • sinon, il vous faudra éditer le fichier en conflit, la plupart du temps en mélangeant les deux codes

Dans tous les cas, une fois le conflit résolu, il vous faudra ajouter les fichiers précédemment en conflit via git add, puis faire git commit.

Attention

Fusionner des fichiers binaires n'a pas de sens sous Git, tout changement d'un fichier binaire signifie remplacement complet.

Abandon de fusion

Dans certains cas, vous commencez une fusion avec git merge puis en analysant les conflits vous vous rendez compte que cette fusion est soit inutile, soit dangereuse en l'état (trop de modifications non compatibles, changement de l'architecture, etc...).

Vérifiez d'abord que vous avez bien une fusion en cours avec git status.

Vous pouvez alors arrêter la fusion:

git merge --abort

Puis vérifiez que tout c'est bien passé avec git status.

Une fois la fusion arrêtée, Git aura remis votre copie de travail dans l'état précédent la fusion.

Git mergetool/intégration aux IDE

Pour vous aider à résoudre les conflits, vous pouvez utiliser la commande git mergtool ou des fonctions intégrées à votre IDE.

Plus: