web-dev-qa-db-fra.com

Résoudre un conflit Git avec des fichiers binaires

J'utilise Git sous Windows (msysgit) pour suivre les modifications de certains travaux de conception que j'ai effectués.

Aujourd'hui, je travaille sur un autre PC (avec repo à distance brian) et j'essaie maintenant de fusionner les modifications apportées aujourd'hui dans ma version locale habituelle sur mon ordinateur portable.

Sur mon ordinateur portable, j'ai utilisé git pull brian master pour extraire les modifications dans ma version locale. Tout se passait bien, à l'exception du document principal InDesign - cela se traduit par un conflit.

La version sur le PC (brian) est la dernière que je souhaite conserver, mais je ne sais pas quelles commandes indiquent au référentiel de l’utiliser.

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

Est-ce que quelqu'un peut-il me montrer la bonne direction?

432
Kevin Wilson

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

$ git checkout --theirs -- path/to/conflicted-file.txt

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

$ git checkout --ours -- path/to/conflicted-file.txt
796
mipadi

Vous devez résoudre le conflit manuellement (copier le fichier sur), puis le valider (que vous l'ayez copié ou utilisé avec la version locale), comme ceci

git commit -a -m "Fix merge conflict in test.foo"

Normalement, Git s'auto-valide après la fusion, mais lorsqu'il détecte des conflits, il ne peut pas le résoudre tout seul. Il applique tous les correctifs qu'il a détectés et vous laisse le reste à résoudre et à valider manuellement. L'entrée de blog --- (Git Merge Man Page , l'entrée Git-SVN Crash Course ou this ) pourrait éclaircir la façon dont elle est censée fonctionner.

Edit: Voir l'article ci-dessous, vous n'êtes pas obligé de copier les fichiers vous-même, vous pouvez utiliser

git checkout --ours -- path/to/file.txt
git checkout --theirs -- path/to/file.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.

Merci de marquer la réponse de mipadis comme étant la réponse correcte.

143
VolkA

Vous pouvez également surmonter ce problème avec

git mergetool

ce qui fait que git crée des copies locales du binaire en conflit et génère votre éditeur par défaut:

  • {conflicted}.HEAD
  • {conflicted}
  • {conflicted}.REMOTE

Évidemment, vous ne pouvez pas éditer utilement des fichiers binaires dans un éditeur de texte. Au lieu de cela, vous copiez le nouveau fichier {conflicted}.REMOTE sur {conflicted} sans fermer l'éditeur. Ensuite, lorsque vous fermez l'éditeur, git verra que la copie de travail non décorée a été modifiée et que le conflit de fusion est résolu de la manière habituelle.

111
RobM

Pour résoudre en gardant la version dans votre branche actuelle (ignorez la version de la branche dans laquelle vous fusionnez), ajoutez et validez le fichier:

git commit -a

Pour résoudre le problème en écrasant la version de votre branche actuelle par celle de la branche dans laquelle vous fusionnez, vous devez d'abord récupérer cette version dans votre répertoire de travail, puis l'ajouter/la valider:

git checkout otherbranch theconflictedfile
git commit -a

expliqué plus en détail

16
Joshua Flanagan

la réponse de mipadi n'a pas fonctionné pour moi, je devais le faire:

git checkout - votre chemin/vers/fichier.bin

ou, pour garder la version en cours de fusion dans:

git checkout - leur chemin/vers/fichier.bin

ensuite

git add path/to/file.bin

Et puis j'ai pu refaire "git mergetool" et continuer jusqu'au conflit suivant.

10
kris

À partir de la _git checkout_ docs

_git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>..._

--ours
--theirs
Lorsque vous extrayez des chemins de l’index, recherchez l’étape 2 (ours) ou 3 (theirs) pour les chemins non fusionnés.

L'index peut contenir des entrées non fusionnées en raison d'une fusion précédente ayant échoué. Par défaut, si vous essayez d'extraire une telle entrée de l'index, l'opération d'extraction échouera et rien ne sera extrait. Utiliser _-f_ ignorera ces entrées non fusionnées. Le contenu d'un côté spécifique de la fusion peut être extrait de l'index en utilisant _--ours_ ou _--theirs_. Avec _-m_, les modifications apportées au fichier d'arborescence de travail peuvent être ignorées pour recréer le résultat de la fusion en conflit d'origine.

6
user456814

Cette procédure consiste à résoudre les conflits de fichiers binaires après avoir soumis une demande d'extraction à Github:

  1. Donc sur Github, vous avez trouvé que votre demande d'extraction avait un conflit sur un fichier binaire.
  2. Retournez maintenant dans la même branche git sur votre ordinateur local.
  3. Vous (a) re-créez/reconstruisez à nouveau ce fichier binaire, et (b) validez le fichier binaire obtenu dans cette même branche git.
  4. Ensuite, vous repoussez cette même branche git à Github.

Sur Github, sur votre demande de tirage, le conflit devrait disparaître.

5
david m lee

Je suis tombé sur un problème similaire (vouloir tirer un commit contenant certains fichiers binaires, ce qui a provoqué des conflits lors de la fusion), mais une solution différente pouvant être résolue entièrement à l’aide de git (c’est-à-dire ne pas avoir à copier manuellement les fichiers). Je pensais l'inclure ici pour au moins pouvoir m'en souvenir la prochaine fois que j'en aurais besoin. :) Les étapes ressemblent à ceci:

% git fetch

Cela récupère les dernières validations du référentiel distant (vous devrez peut-être spécifier un nom de branche distante, en fonction de votre configuration), mais n'essaiera pas de les fusionner. Il enregistre le commit dans FETCH_HEAD

% git checkout FETCH_HEAD stuff/to/update

Cela prend la copie des fichiers binaires que je veux et écrase ce qui est dans l’arbre de travail avec la version récupérée à partir de la branche distante. git n'essaie pas de fusionner, vous obtenez donc une copie exacte du fichier binaire de la branche distante. Une fois cela fait, vous pouvez ajouter/valider la nouvelle copie comme d'habitude.

3
Brian Webster

J'ai rencontré deux stratégies de gestion de diff/fusion de fichiers binaires avec Git sous Windows.

  1. Tortoise git vous permet de configurer des outils de diff/fusion pour différents types de fichiers en fonction de leurs extensions. Voir 2.35.4.3. Paramètres avancés de Diff/Merge http://tortoisegit.org/docs/tortoisegit/tgit-dug-settings.html . Cette stratégie repose bien sûr sur la disponibilité d’outils de différenciation/fusion adaptés.

  2. En utilisant les attributs git, vous pouvez spécifier un outil/une commande pour convertir votre fichier binaire en texte, puis laisser votre outil diff/merge par défaut agir à sa place. Voir http://git-scm.com/book/it/v2/Customizing-Git-Git-Attributes . L'article donne même un exemple d'utilisation de métadonnées pour diff images.

J'ai eu les deux stratégies pour travailler avec des fichiers binaires de modèles de logiciels, mais nous sommes allés avec tortoise git car la configuration était facile.

1
BoJohDoh

Si le binaire est quelque chose de plus qu'une dll ou quelque chose qui peut être édité directement ​​comme une image, ou un fichier blend (et vous n'avez pas besoin de la supprimer ou de la supprimer) fichier ou l’autre) une vraie fusion ressemblerait à ceci:

Je suggère de rechercher un outil de diff orienté vers ce que vous êtes un fichier binaire, par exemple, il y en a quelques-uns gratuits pour les fichiers image par exemple

et les comparer.

S'il n'y a pas d'outil de comparaison pour comparer vos fichiers, alors si vous avez le générateur d'origine du fichier bin (c'est-à-dire il existe un éditeur pour cela .. comme blender 3d, vous pouvez ensuite inspecter manuellement ces fichiers, consulter les journaux et demander à l’autre personne ce qu’il faut inclure) et créer une sortie des fichiers avec https: // git-scm .com/book/es/v2/Git-Tools-Advanced-Merging # _manual_remerge

$ git show :1:hello.blend > hello.common.blend $ git show :2:hello.blend > hello.ours.blend $ git show :3:hello.blend > hello.theirs.blend

1
tyoc213

J'utilise Git Workflow for Excel - https://www.xltrail.com/blog/git-workflow-for-Excel application pour résoudre la plupart de mes problèmes de fusion liés aux fichiers binaires. Cette application open source m'aide à résoudre les problèmes de manière productive sans perdre trop de temps et me permet de choisir la bonne version du fichier sans confusion.

0
Siddhartha Thota

mon cas semble être un bug .... en utilisant git 2.21.0

J'ai fait un pull ... il s'est plaint de fichiers binaires:

warning: Cannot merge binary files: <path>
Auto-merging <path>
CONFLICT (content): Merge conflict in <path>
Automatic merge failed; fix conflicts and then commit the result.

Et puis, rien dans aucune des réponses ici n'a abouti à une sortie qui ait un sens.

Si je regarde quel fichier j'ai maintenant ... c'est celui que j'ai édité. Si je fais soit:

git checkout --theirs -- <path>
git checkout --ours -- <path>

Je reçois la sortie:

Updated 0 paths from the index

et j'ai toujours ma version du fichier. Si je suis et puis la caisse, il dira 1 à la place, mais il me donne toujours ma version du fichier.

git Mergetool dit

No files need merging

et le statut git dit

    All conflicts fixed but you are still merging.
    (use "git commit" to conclude merge)

Une option est de annuler le commit ... mais j'ai été malchanceux et j'ai eu beaucoup de commits, et ce mauvais était le premier. Je ne veux pas perdre de temps à répéter cela.

donc pour résoudre cette folie:

Je viens de courir

git commit

qui perd la version distante et probablement une certaine perte d’espace en stockant un fichier binaire supplémentaire ... puis

git checkout <commit where the remote version exists> <path>

ce qui me rend la version distante

puis édité à nouveau le fichier ... puis validation et Push, ce qui signifie probablement encore une fois gaspiller de l'espace avec une autre copie du fichier binaire.

0
Peter