Linux Embedded

Le blog des technologies libres et embarquées

Mini HowTo: git merge et fichiers binaires

Le gestionnaire de version git est surtout utilisé pour conserver les sources des programmes, mais il peut parfois être pertinent d'y conserver des fichiers binaires. Le cas qui va nous intéresser est celui de documents LibreOffice conservés sous git (typiquement la documentation d’un projet). Toutefois la méthode peut être adaptée à tous types de documents binaire pour lesquels il existe un moyen (plus ou moins simple) de fusionner les différences entre deux versions.

Considérons un fichier « documentation.odt » commencé et partagé (git push). Sur la base de ce document, deux personnes (Alice et Bob) vont faire des modifications. Alice va finaliser sa version la première et la pousser vers le dépôt central. Bob va ensuite terminer sa propre version et l’enregistrer sous git. En revanche, quand il va vouloir pousser sa version il va devoir fusionner (git merge) les modifications d’Alice avec les siennes.

Fusion

Avant de commencer le dépôt vu par Bob ressemble à ça :

Dépôt avant fusion
Bob commence par fusionner normalement avec git :

git merge origin/master

Évidemment il y a un conflit :

warning: Cannot merge binary files: documentation.odt (HEAD vs. origin/master)

Auto-merging documentation.odt
CONFLICT (content): Merge conflict in documentation.odt
Automatic merge failed; fix conflicts and then commit the result.

Résolution du conflit

Récupération des différentes versions

Bob va devoir effectuer la fusion à la main, mais pour cela il a besoin des deux versions du document, or git ne lui a laissé que la sienne. Dans cette situation, git checkout fourni deux options --theirs et --ours qui permettent de récupérer la version provenant de l’autre branche ou la nôtre.

Bob récupère la version d’Alice

git checkout --theirs -- documentation.odt

Cette version étant différente de la sienne il en fait une copie.

cp documentation.odt documentation-A.odt

Puis il demande à git de lui rendre sa version :

git checkout --ours -- documentation.odt

Il dispose maintenant des deux versions.

Fusion sous LibreOffice

Il lance donc LibreOffice et ouvre le document. Puis dans le menu « Édition » il sélectionne « Comparer le document... » et ouvre la copie du document d’Alice. Il peut ensuite accepter ou refuser les modifications une à une, et même éditer le document au besoin. Enfin, il enregistre le document écrasant sa version originale.

Finalisation du « commit »

Le fichier « documentation.odt » contient maintenant la version fusionnée manuellement, il ne reste plus qu’à finir le « commit » et ceci de manière tout à fait normale :

git add documentation.odt
git commit

Une fois la fusion réalisée, l’historique git se présente de la même manière que pour un fichier texte. On retrouve le commit et ses deux parents, chacun apportant son lot de modifications :

Dépôt après fusion

Parent: 1047e73 (Bob modifie la documentation)
Parent: 21a6214 (Ajout par Alice)
Branche: master
    Merge remote-tracking branch 'origin/master'

    Conflicts:
    	documentation.odt
--------------------- documentation.odt ---------------------
index 31aa8d3,b172323..c7f30ab
@@@ -4,5 -4,5 +4,7 @@@ Documentatio

  Ceci est la documentation du projet.

+ Alice ajoute un paragraphe décrivant une partie du projet.
+
+Sur la même base, Bob modifie aussi la documentation.
+

Note : l’affichage des différences entre les versions est réalisé à l’aide d’odt2txt comme décrit dans un précédent article.

Une alternative pour la fusion : git mergetool

Pour la phase de fusion, git permet d’utiliser un outil de fusion extérieur à l’aide de la commande « git mergetool ».

Dans le cas de LibreOffice, il n’existe pas d’option de ligne de commande permettant de lancer la comparaison des documents directement. Il est toutefois possible d’utiliser git mergetool qui se chargera de récupérer les différentes versions, d’utiliser LibreOffice depuis un autre terminal, puis de fermer l’outil externe une fois la fusion réalisé.
Les fichiers sont nommés de la façon suivante par git mergetool :

  • Le fichier original est copiée avec l'extension « .HEAD ».
  • Le fichier fusionné (l'original aussi au départ) est conservé.
  • Le fichier de l'autre branche est copié avec l'extension « .REMOTE ».

Cette approche prendrait tout son sens si l’on disposait d’un outil de fusion accessible en ligne de commande, ce n’est pas le cas de LibreOffice mais ça l’est peut être pour d’autres formats binaires.

Mots-clés :

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.