523 votes

Résoudre un conflit Git avec des fichiers binaires

J'ai utilisé Git sur Windows (msysgit) pour suivre les modifications de certains travaux de conception que j'ai réalisés.

Aujourd'hui, j'ai travaillé sur un autre PC (avec un dépôt distant brian) et j'essaie maintenant de fusionner les modifications effectuées aujourd'hui dans ma version locale habituelle sur mon ordinateur portable.

Sur mon ordinateur portable, j'ai utilisé git pull brian master pour récupérer les modifications dans ma version locale. Tout s'est bien passé sauf pour le document principal InDesign - cela se présente comme un conflit.

La version sur le PC (brian) est la dernière que je veux conserver mais je ne sais pas quelles commandes indiquent au dépôt d'utiliser cette version.

J'ai essayé de copier directement le fichier sur mon ordinateur portable mais cela semble compromettre tout le processus de fusion.

Quelqu'un peut-il me guider dans la bonne direction?

968voto

mipadi Points 135410

git checkout accepte une option --ours ou --theirs pour des cas comme celui-ci. Donc si vous avez un conflit de fusion, et que vous savez que vous voulez juste le fichier de la branche que vous fusionnez, vous pouvez faire :

$ git checkout --theirs -- chemin/vers/fichier-en-conflit.txt

pour utiliser cette version du fichier. De même, si vous savez que vous voulez votre version (et non celle qui est fusionnée), vous pouvez utiliser

$ git checkout --ours -- chemin/vers/fichier-en-conflit.txt

58 votes

J'ai dû exécuter 'git reset HEAD chemin/vers/fichier-en-conflit.txt' sur le fichier avant d'utiliser --ours, sinon cela semblait ne pas avoir d'effet.

7 votes

@Zitrax Avez-vous différencié le fichier après avoir exécuté git checkout --ours? La page de manuel suggère (à mon avis) que checkout --ours/--theirs va supprimer le changement de la liste "both modified, need merge" et l'ajouter à l'index, et je pense que ce n'est pas correct. Je crois que vous devrez exécuter git add après le checkout.

16 votes

Note : vous voudrez toujours faire "git add conflicted-file.txt" et "git commit". Heureusement, lorsque j'ai essayé, le message de commit était pré-rempli avec une note sur le conflit.

155voto

VolkA Points 10297

Vous devez résoudre le conflit manuellement (copier le fichier) puis valider le fichier (peu importe si vous l'avez copié ou utilisé la version locale) comme ceci

git commit -a -m "Corriger le conflit de fusion dans test.foo"

Git commet normalement automatiquement après fusion, mais lorsqu'il détecte des conflits qu'il ne peut pas résoudre seul, il applique tous les correctifs qu'il a trouvés et vous laisse le reste pour que vous le résolviez et le validiez manuellement. La page de documentation de fusion Git, le cours accéléré Git-SVN ou cet billet de blog pourraient éclairer sur comment cela est censé fonctionner.

Édit : Voir le post ci-dessous, vous n'avez pas vraiment à copier les fichiers vous-même, mais vous pouvez utiliser

git checkout --ours -- chemin/vers/fichier.txt
git checkout --theirs -- chemin/vers/fichier.txt

pour sélectionner la version du fichier que vous voulez. Copier / éditer le fichier ne sera nécessaire que si vous voulez un mélange des deux versions.

Veuillez marquer la réponse de mipadis comme correcte.

1 votes

Merci pour ça. Je n'étais pas sûr s'il y avait une sorte de façon intégrée de marquer un fichier comme le 'correct'. Explique pourquoi je n'ai pas pu trouver la commande inexistante cependant!

0 votes

Oui, c'est un peu contre-intuitif - quelque chose comme git resolve serait bien, mais ce serait aussi une étape supplémentaire ...

126voto

RobM Points 2681

Vous pouvez également surmonter ce problème avec

git mergetool

ce qui fait que git crée des copies locales des fichiers binaires en conflit et ouvre votre éditeur par défaut dessus :

  • {conflit}.HEAD
  • {conflit}
  • {conflit}.REMOTE

De toute évidence, vous ne pouvez pas modifier des fichiers binaires de manière utile dans un éditeur de texte. Au lieu de cela, vous copiez le fichier {conflit}.REMOTE par dessus {conflit} sans fermer l'éditeur. Ensuite, lorsque vous fermez l'éditeur, git remarquera que la copie de travail non décorée a été modifiée et votre conflit de fusion sera résolu de la manière habituelle.

10 votes

Si les fichiers sont volumineux ou si vous ne voulez pas risquer d'ouvrir du binaire dans un éditeur de texte, vous pouvez appuyer sur ctrl+c à l'invite de mergetool ("Appuyez sur Entrée pour démarrer l'outil de résolution de fusion") et git laissera les fichiers supplémentaires en place. Ensuite, vous pouvez les modifier ou les fusionner dans un outil externe (utile pour les formats de documents binaires tels que LibreOffice/OpenOffice/MSWord) et enregistrer le résultat sous le nom de fichier d'origine. Pour informer git que le conflit est résolu, git add le nom de fichier d'origine, puis vous pouvez terminer la fusion commit.

20voto

Joshua Flanagan Points 5907

Pour résoudre en conservant la version de votre branche actuelle (ignorez la version de la branche que vous fusionnez), ajoutez simplement le fichier et commitez :

git commit -a

Pour résoudre en écrasant la version de votre branche actuelle avec la version de la branche que vous fusionnez, vous devez d'abord récupérer cette version dans votre répertoire de travail, puis l'ajouter/commettre :

git checkout autrebranche lefichierconflit
git commit -a

Expliqué plus en détail

1 votes

Je préfère cette variante à la réponse acceptée, car elle est plus intuitive, surtout si l'on considère que la signification de "--le-nôtre" et "--le-leur" est inversée en cas de rebasage.

6voto

Cupcake Points 22154

À partir de la git checkout docs

git checkout [-f|--ours|--theirs|-m|--conflict=] [<tree-ish>] [--] <paths>...</code> </p> <p><strong><code>--ours</code></strong><br> <strong><code>--theirs</code></strong><br> Lorsque vous vérifiez des chemins depuis l'index, vérifiez l'étape #2 (<code>ours</code>) ou #3 (<code>theirs</code>) pour les chemins non fusionnés.</p> <p>L'index peut contenir des entrées non fusionnées en raison d'une fusion précédente échouée. Par défaut, si vous essayez de vérifier une telle entrée depuis l'index, l'opération de vérification échouera et rien ne sera vérifié. L'utilisation de <code>-f</code> ignorera ces entrées non fusionnées. Le contenu d'un côté spécifique de la fusion peut être vérifié depuis l'index en utilisant <code>--ours</code> ou <code>--theirs</code>. Avec <code>-m</code>, les modifications apportées au fichier de l'arborescence de travail peuvent être ignorées pour recréer le résultat de fusion en conflit d'origine.</p> </blockquote></x-turndown>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X