203 votes

Comment puis-je ignorer les modifications à distance et marquer un fichier comme étant "résolu" ?

J'ai des fichiers locaux, je tire de la branche distante et il y a des conflits. Je sais que j'aimerais conserver mes modifications locales et ignorer les modifications distantes qui causent des conflits. Existe-t-il une commande que je puisse utiliser pour dire "marquer tous les conflits comme résolus, utiliser le local" ?

2 votes

La réponse ci-dessous m'a beaucoup éclairé. Je recommande à tous les utilisateurs de GIT qui ne sont pas des experts de lire tous les commentaires sous le post ci-dessous, et merci Brian !

346voto

Brian Campbell Points 101107

git checkout a le --ours pour vérifier la version du fichier que vous avez localement (par opposition à l'option --theirs qui est la version que vous avez introduite). Vous pouvez passer . a git checkout pour lui dire de vérifier tout ce qui se trouve dans l'arbre. Vous devez ensuite marquer les conflits comme résolus, ce que vous pouvez faire avec git add et de valider votre travail une fois qu'il est terminé :

git checkout --ours .  # checkout our local version of all files
git add -u             # mark all conflicted files as merged
git commit             # commit the merge

Notez que les . dans le git checkout commande. C'est très important, et il est facile de passer à côté. git checkout a deux modes ; l'un dans lequel il change de branche, et l'autre dans lequel il vérifie les fichiers de l'index dans la copie de travail (parfois en les tirant d'abord dans l'index à partir d'une autre révision). La distinction se fait en fonction du nom de fichier passé ; si vous n'avez pas passé de nom de fichier, il essaie de changer de branche (bien que si vous ne passez pas de branche non plus, il essaiera juste de vérifier la branche actuelle à nouveau), mais il refuse de le faire s'il y a des fichiers modifiés que cela affecterait. Donc, si vous voulez un comportement qui écrase les fichiers existants, vous devez passer le paramètre . ou un nom de fichier afin d'obtenir le second comportement de git checkout .

C'est aussi une bonne habitude à prendre, lorsque l'on passe un nom de fichier, de le faire précéder de -- , tels que git checkout --ours -- <filename> . Si vous ne faites pas cela, et que le nom du fichier correspond au nom d'une branche ou d'une balise, Git pensera que vous voulez extraire cette révision, au lieu d'extraire ce nom de fichier, et utilisera donc la première forme de la balise checkout commande.

Je m'étendrai un peu plus sur la manière dont les conflits et les fusion dans Git. Lorsque vous fusionnez le code de quelqu'un d'autre (ce qui se produit également lors d'une extraction ; une extraction est essentiellement une récupération suivie d'une fusion), il y a quelques situations possibles.

Le plus simple est que vous soyez sur la même révision. Dans ce cas, vous êtes "déjà à jour" et rien ne se passe.

Une autre possibilité est que leur révision soit simplement un descendant de la vôtre, auquel cas vous aurez par défaut une "fusion accélérée", dans laquelle votre HEAD est simplement mis à jour avec leur commit, sans qu'aucune fusion n'ait lieu (ceci peut être désactivé si vous voulez vraiment enregistrer une fusion, en utilisant la commande --no-ff ).

Il arrive ensuite que l'on doive fusionner deux révisions. Dans ce cas, il y a deux résultats possibles. La première est que la fusion se déroule proprement ; toutes les modifications se trouvent dans des fichiers différents, ou dans les mêmes fichiers, mais à une distance suffisante pour que les deux ensembles de modifications puissent être appliqués sans problème. Par défaut, lorsqu'une fusion propre se produit, elle est automatiquement validée, bien que vous puissiez désactiver cela avec la commande --no-commit si vous devez le modifier au préalable (par exemple, si vous renommez la fonction foo a bar et quelqu'un d'autre ajoute un nouveau code qui appelle foo il fusionnera proprement, mais produira un arbre brisé, donc vous voudrez peut-être nettoyer cela dans le cadre du commit de fusion afin d'éviter d'avoir des commits brisés).

La dernière possibilité est qu'il y ait une véritable fusion et qu'il y ait des conflits. Dans ce cas, Git effectuera la fusion autant qu'il le peut, et produira des fichiers avec des marqueurs de conflit ( <<<<<<< , ======= y >>>>>>> ) dans votre copie de travail. Dans l'index (également connu sous le nom de "zone de transit" ; l'endroit où les fichiers sont stockés par l git add avant de les valider), vous aurez 3 versions de chaque fichier avec des conflits ; il y a la version originale du fichier de l'ancêtre des deux branches que vous fusionnez, la version de HEAD (votre côté de la fusion), et la version de la branche distante.

Pour résoudre le conflit, vous pouvez soit éditer le fichier qui se trouve dans votre copie de travail, en supprimant les marqueurs de conflit et en corrigeant le code pour qu'il fonctionne. Vous pouvez également vérifier la version d'un côté ou de l'autre de la fusion, en utilisant la commande git checkout --ours o git checkout --theirs . Une fois que vous avez mis le fichier dans l'état souhaité, vous indiquez que vous avez fini de fusionner le fichier et qu'il est prêt à être livré en utilisant la commande git add puis vous pouvez valider la fusion avec git commit .

8 votes

Il convient de noter que git add --all ajoute tous les fichiers au référentiel, ce qui risque d'ajouter plus de fichiers que prévu, à moins que votre logiciel .gitignore sont en parfait état. git add -u est probablement plus adapté à cette situation, car il est moins probable que des modifications soient apportées aux fichiers suivis et que vous ne souhaitiez pas les ajouter lors de la résolution d'une fusion.

0 votes

Oups, désolé. C'est ce que je voulais dire. Je l'ai corrigé maintenant.

1 votes

Merci pour votre réponse détaillée. J'ai en fait essayé git checkout --ours et j'ai reçu un message d'erreur (dont je ne me souviens plus maintenant). Les fichiers en question sont des dll (nous en avons quelques uns que nous cachons, des références de tierces parties principalement) et je voulais juste dire 'ok ma copie est celle que je veux mais l'erreur était quelque chose comme 'can't checkout while merging'..... Je garderai cet article comme référence et la prochaine fois que cela se produira, j'essaierai à nouveau et je verrai si cela fonctionne ou si je peux afficher ce message. Merci encore

25voto

VonC Points 414372

Assurez-vous de le conflit origine: si elle est le résultat d'un git merge, voir Brian Campbell's réponse.

Mais si c'est le résultat d'un git rebase, afin d'éliminer à distance (leurs) les modifications et l'utilisation locale des modifications, il vous suffit de faire un:

git checkout --theirs -- .

Voir "Pourquoi est-ce le sens de "ours" et "theirs" inversé"" pour voir comment ours et theirs sont échangés au cours d'un rebase (parce que l' amont de la branche de l'extraction).

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