web-dev-qa-db-fra.com

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

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

194
Tom DeMille

git checkout a le --ours option pour extraire la version du fichier que vous aviez localement (par opposition à --theirs, qui est la version que vous avez introduite). Tu peux passer . à git checkout pour lui dire de tout vérifier dans l’arbre. Ensuite, vous devez marquer les conflits comme résolus, ce que vous pouvez faire avec git add , et engagez votre travail une fois 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

Noter la . dans le git checkout commande. C'est très important et facile à manquer. git checkout a deux modes; un dans lequel il change de branche et un autre dans lequel il contrôle les fichiers de l'index dans la copie de travail (en les extrayant parfois dans l'index d'une première révision). Cela permet de distinguer si vous avez transmis un nom de fichier; si vous n'avez pas passé de nom de fichier, il essaie de changer de branche (mais si vous ne passez pas de branche non plus, il essaiera simplement de vérifier à nouveau la branche actuelle), mais il refuse de le faire s'il existe des fichiers modifiés. que cela aurait pour effet. Donc, si vous voulez un comportement qui écrasera les fichiers existants, vous devez passer . ou un nom de fichier pour obtenir le deuxième comportement de git checkout.

C’est aussi une bonne habitude d’avoir, lorsqu’on passe un nom de fichier, le compenser avec --, tel que git checkout --ours -- <filename>. Si vous ne le faites pas et que le nom du fichier correspond au nom d'une branche ou d'une balise, Git pensera que vous souhaitez extraire cette révision au lieu d'extraire ce nom de fichier, et utilisez donc le premier formulaire checkout commande.

Je vais développer un peu sur la façon dont les conflits et fusion fonctionnent dans Git. Lorsque vous fusionnez dans le code d'une autre personne (ce qui se produit également lors d'une extraction; une extraction est essentiellement une opération d'extraction suivie d'une fusion), il existe peu de situations possibles.

Le plus simple est que vous êtes 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 ne soit qu'un descendant du vôtre. Dans ce cas, vous aurez par défaut une "fusion rapide" dans laquelle votre HEAD vient juste d'être mise à jour avec leur commit, sans fusion ceci peut être désactivé si vous voulez vraiment enregistrer une fusion, en utilisant --no-ff).

Ensuite, vous entrez dans les situations dans lesquelles vous devez réellement fusionner deux révisions. Dans ce cas, il y a deux résultats possibles. La première est que la fusion se produit proprement; toutes les modifications sont dans des fichiers différents ou dans les mêmes fichiers, mais suffisamment éloignées pour que les deux ensembles de modifications puissent être appliqués sans problème. Par défaut, lorsqu’une fusion est effectuée, elle est automatiquement validée, mais vous pouvez la désactiver avec --no-commit si vous devez le modifier au préalable (par exemple, si vous renommez la fonction foo en bar et que quelqu'un d'autre ajoute un nouveau code appelant foo, il sera fusionné proprement. , mais produisez un arbre cassé, vous pouvez donc le nettoyer dans le cadre du commit de fusion afin d’éviter d’avoir des commits cassés).

La dernière possibilité est qu’il y ait une véritable fusion et des conflits. Dans ce cas, Git fera autant de fusion que possible et produira des fichiers avec des marqueurs de conflit (<<<<<<<, =======, et >>>>>>>) dans votre copie de travail. Dans l'index (également appelé "zone de stockage intermédiaire"; l'emplacement où les fichiers sont stockés par git add avant de les commettre), vous aurez 3 versions de chaque fichier avec des conflits; il existe 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.

Afin de résoudre le conflit, vous pouvez soit modifier 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. Ou, vous pouvez extraire la version de l’un ou l’autre des côtés de la fusion en utilisant git checkout --ours ou git checkout --theirs. Une fois que vous avez placé le fichier dans l'état souhaité, vous indiquez que vous avez fini de le fusionner et qu'il est prêt à être utilisé avec git add, puis vous pouvez valider la fusion avec git commit.

320
Brian Campbell

Assurez-vous du conflit Origine: si c'est le résultat d'un git merge, voir Brian Campbell 's réponse .

Mais si est le résultat d'un git rebase, pour ignorer à distance (leurs) modifications et utiliser local changements, vous devez faire un:

git checkout --theirs -- .

Voir " Pourquoi la signification de" ours "et" theirs "est-elle inversée" "pour voir comment ours et theirs sont échangés lors d'une base (parce que la branche en amont est extraite).

22
VonC