179 votes

Est-il possible pour git-merge d'ignorer les différences de fin de ligne ?

Est-il possible pour git merge pour ignorer les différences de fin de ligne ?

Peut-être que je pose la mauvaise question ... mais :

J'ai essayé d'utiliser config.crlf input mais les choses sont devenues un peu désordonnées et hors de contrôle, surtout quand je l'ai appliqué. après coup .

D'une part, l'application de cette configuration après coup ne semble pas affecter les fichiers qui ont été livrés au référentiel avant l'application de cette option. Une autre chose est que soudainement tous les commits résultent maintenant en beaucoup de messages d'avertissement ennuyeux sur CRLF étant converti en LF.

Pour être honnête, je ne me soucie pas vraiment de la terminaison de ligne utilisée, je préfère personnellement le style Unix \n mais peu importe. Tout ce qui m'importe, c'est que git merge d'être un peu plus malin et d'ignorer les différences de fin de ligne.

Parfois, j'ai deux fichiers identiques, mais git les marquerait comme étant en conflit (et le conflit est le ensemble du site ) simplement parce qu'ils utilisent un caractère de fin de ligne différent.

Mise à jour :

J'ai découvert que git diff accepte un --ignore-space-at-eol serait-il possible de laisser git merge utiliser cette option également ?

38 votes

Oh, j'aimerais bien. Ce truc de fin de ligne dans Git est totalement cassé.

0 votes

Il ne semble pas que cela puisse être fait directement, mais cet article suggère une solution de contournement. osdir.com/ml/git/2009-02/msg02532.html

0 votes

Je viens d'ajouter un cas de test illustrant le fait que ces outils de fusion tiers ignorent le style eol pendant une fusion.

137voto

VonC Points 414372

Mise à jour 2013 :

Les versions plus récentes de git autorisent l'utilisation de la stratégie "merge with". recursive et stratégie option ( -X ):

Mais en utilisant " -Xignore-space-change " est également une possibilité


jakub.g également commentaires que le les stratégies fonctionnent aussi avec le "cherry-picking :

git cherry-pick abcd123456 --strategy=recursive --strategy-option=renormalize 

Cela fonctionne beaucoup mieux que ignore-all-space .


Avant Git 2.29 (Q4 2020), toutes les opérations "mergy" qui utilisent en interne la machinerie merge-recursive doivent honorer l'attribut merge.renormalize mais beaucoup d'entre eux ne l'ont pas fait.

Ver commettre 00906d6 , commettre 8d55225 , commettre 6f6e7cf , commettre fe48efb (03 août 2020) par Elijah Newren ( newren ) .
(fusionné par Junio C Hamano -- gitster -- en commit 4339259 10 août 2020)

merge : faire merge.renormalize travail pour toutes les utilisations des machines de fusion

Signé par : Elijah Newren

Le merge La commande '' n'est pas la seule à effectuer des fusions ; d'autres commandes telles que checkout -m ou rebase font aussi bien l'affaire.

Malheureusement, la seule partie du code qui vérifiait le " merge.renormalize Le réglage de la configuration " " était dans builtin/merge.c ce qui signifie qu'il ne peut affecter que les fusions réalisées par la fonction " merge Commande ".

Déplacer la gestion de ce paramètre de configuration vers merge_recursive_config() afin que d'autres commandements puissent en bénéficier également.


Réponse originale (mai 2009)

Le correctif pour ignorer le style eol a été proposé en Juin 2007 mais elle ne concerne que git diff --ignore-space-at-eol pas git merge .

A l'époque, la question a été posée :

Devrait --ignore-space-at-eol être une option pour git-merge ?
Les fusions sont le domaine où cette fonctionnalité est importante.
Quelle est la sémantique d'une fusion résolue automatiquement avec ces options en vigueur -- sont-elles seulement utilisées pour la détection des renommages, ou est-ce que, par exemple, nous ne signalons pas les conflits avec seulement des changements d'espacement ? Et si nous ne le faisons pas, quelle version acceptons-nous automatiquement ?

Julio C Hamano n'était pas vraiment enthousiaste :

C'est certainement tentant, mais je pense que cela devrait être laissé pour les tours ultérieurs.
Je soupçonne que cela introduirait un concept de deux types différents de différences, l'une à traiter mécaniquement (c'est-à-dire à utiliser dans la fusion avec "git-merge-recursive", et à appliquer avec "git-am"), et une autre à inspecter par des humains pour la comprendre.
Il peut souvent être utile de fusionner les données d'entrée dans ce dernier cas, même si les résultats de la comparaison des fichiers d'entrée fusionnés peuvent ne pas être facilement utilisables pour une application mécanique.

L'idée générale, quand il s'agit de git merge est de se fier à l'outil de fusion tiers.

Par exemple, j'ai configuré DiffMerge pour être l'outil de fusion de Git, en définissant une jeu de règles qui permettent à cet outil de fusion d'ignorer eol pour certains types de fichiers.


Installation sur Windows, avec MSysGit1.6.3, soit pour DOS, soit pour la session bash de Git, avec DiffMerge ou KDiff3 :

  • placer un répertoire dans votre PATH (ici : c:\HOMEWARE\cmd ).
  • ajouter dans ce répertoire le script merge.sh (wrapper pour votre outil de fusion préféré)

merge.sh :

#!/bin/sh

# Passing the following parameters to mergetool:
#  local base remote merge_result

alocal=$1
base=$2
remote=$3
result=$4

if [ -f $base ]
then
    #"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$alocal" "$base" "$remote" -m --result="$result" --title1="Mine" --title2="Merging to: $result" --title3="Theirs"

    # for merge respecting eol, KDiff3 is better than DiffMerge (which will always convert LF into CRLF)
    # KDiff3 will display eol choices (if Windows: CRLF, if Unix LF)
    "C:/Program Files/KDiff3/kdiff3.exe" -m "$base" "$alocal" "$remote" -o "$result"
else
    #there is not always a common ancestor: DiffMerge needing 3 files, BASE will be the result
    #"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$alocal" "$result" "$remote" -m --result="$result" --title1="Mine" --title2="Merging to: $result" --title3="Theirs"

    # KDiff3 however does know how to merge based on 2 files (not just 3)
    "C:/Program Files/KDiff3/kdiff3.exe" -m "$base" "$remote" -o "$result"
fi
  • Déclarer votre wrapper de fusion pour Git

Commandes de configuration Git :

git config --global merge.tool diffmerge
git config --global mergetool.diffmerge.cmd "merge.sh \"$PWD/$LOCAL\" \"$PWD/$BASE\" \"$PWD/$REMOTE\" \"$PWD/$MERGED\"
git config --global mergetool.diffmerge.trustExitCode false
git config --global mergetool.diffmerge.keepBackup false
  • Vérifiez que autoCRLF est faux

configuration de git au niveau du système :

git config ---system core.autoCRLF=false
  • Test que, lorsque deux lignes sont identiques (mais leurs caractères eol), DiffMerge ou KDiff3 ignorent ces lignes lors d'une fusion.

DOS script (note : le mot La commande dos2unix vient d'ici et est utilisé pour simuler un style eol Unix. Cette commande a été copiée dans le répertoire mentionné au début de cette réponse) :

C:\HOMEWARE\git\test>mkdir test_merge
C:\HOMEWARE\git\test>cd test_merge
C:\HOMEWARE\git\test\test_merge>git init
C:\HOMEWARE\git\test\test_merge>echo a1 > a.txt & echo a2 >> a.txt
C:\HOMEWARE\git\test\test_merge>git add a.txt
C:\HOMEWARE\git\test\test_merge>git commit -m "a.txt, windows eol style"
C:\HOMEWARE\git\test\test_merge>git checkout -b windows
Switched to a new branch 'windows'
C:\HOMEWARE\git\test\test_merge>echo a3 >> a.txt & echo a4 >> a.txt
C:\HOMEWARE\git\test\test_merge>git add a.txt
C:\HOMEWARE\git\test\test_merge>git commit -m "add two lines, windows eol style"
C:\HOMEWARE\git\test\test_merge>git checkout master
C:\HOMEWARE\git\test\test_merge>git checkout -b unix
Switched to a new branch 'unix'
C:\HOMEWARE\git\test\test_merge>echo au3 >> a.txt & echo au4 >> a.txt && echo au5 >> a.txt
C:\HOMEWARE\git\test\test_merge>dos2unix a.txt
Dos2Unix: Processing file a.txt ...
C:\HOMEWARE\git\test\test_merge>git add a.txt
C:\HOMEWARE\git\test\test_merge>git commit -m "add 3 lines, all file unix eol style"
[unix c433a63] add 3 lines, all file unix eol style

C:\HOMEWARE\git\test\test_merge>git merge windows
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
Automatic merge failed; fix conflicts and then commit the result.

C:\HOMEWARE\git\test\test_merge>git ls-files -u
100644 39b4c894078a02afb9b1dfeda6f1127c138e38df 1       a.txt
100644 28b3d018872c08b0696764118b76dd3d0b448fca 2       a.txt
100644 3994da66530b4df80189bb198dcfac9b8f2a7b33 3       a.txt

C:\HOMEWARE\git\test\test_merge>git mergetool
Merging the files: a.txt

Normal merge conflict for 'a.txt':
  {local}: modified
  {remote}: modified
Hit return to start merge resolution tool (diffmerge):

À ce stade (en appuyant sur "retour"), DiffMerge ou KDiff3 s'ouvrira, et vous verrez par vous-même quelles lignes sont réellement fusionnées, et quelles lignes sont ignorées.

Avertissement : le fichier résultat sera toujours en mode Windows eol (CRLF) avec DiffMerge...
KDiff3 propose d'économiser d'une manière ou d'une autre.

0 votes

Merci pour le conseil ! Meld et FileMerge sur Mac semblent être de bonnes applications aussi.

1 votes

Pour info, les stratégies fonctionnent aussi avec sélection de sites : git cherry-pick abcd123456 --strategy=recursive --strategy-option=renormalize (cela fonctionne bien mieux que ignore-all-space )

1 votes

@jakub.g bon point ! Je l'ai inclus dans la réponse pour plus de visibilité.

112voto

Fabio Points 8145

Je cherchais la même réponse et j'ai découvert que este

Fusion de branches avec des attributs checkin/checkout différents

Si vous avez ajouté des attributs à un fichier qui font que le fichier canonique de ce fichier, comme l'ajout d'un fichier de type filtre clean/smudge ou des attributs text/eol/ident, la fusion de tout ce qui est où l'attribut n'est pas en place causerait normalement des conflits de fusion. conflits.

Pour éviter ces conflits de fusion inutiles, on peut demander à git d'exécuter une commande d'effectuer un check-out et un check-in virtuel des trois étapes d'un fichier lorsque d'un fichier lors de la résolution d'une fusion à trois en définissant l'option merge.renormalize en définissant la variable de configuration merge.renormalize. Cela empêche les changements causés par le check-in ne provoquent pas de conflits de fusion intempestifs lorsqu'un fichier converti est fusionné avec un fichier non converti.

Tant qu'un "smudgeclean" donne le même résultat qu'un "clean". même sur des fichiers qui sont déjà smudgés, cette stratégie résout automatiquement résoudra automatiquement tous les conflits liés aux filtres. Les filtres qui n'agissent pas n'agissent pas de cette manière peuvent causer des conflits de fusion supplémentaires qui doivent être résoudre manuellement.

Ainsi, l'exécution de cette commande dans n'importe quel référentiel fera l'affaire :

git config merge.renormalize true

24 votes

Cela mérite désormais d'être la réponse par défaut. Beaucoup de choses ont changé depuis que la question a été posée pour la première fois, la gestion de ce problème par git est maintenant intégrée à merge.renormalize comme vous le dites.

0 votes

C'est juste génial ça sauve ma journée.

25voto

Fab V. Points 392

Après avoir lu https://stackoverflow.com/a/12194759/1441706 y https://stackoverflow.com/a/14195253/1441706

pour moi, cette commande a parfaitement fonctionné :

git merge master -s recursive -X renormalize

7voto

Comme dans cette réponse : https://stackoverflow.com/a/5262473/943928

Vous pouvez essayer : git merge -s recursive -Xignore-space-at-eol

4voto

Ben Hymers Points 3912

Ce que j'ai fait, c'est de tout laisser par défaut (i.e. autocrlf=true), de toucher tous les fichiers (find . -exec touch {} \ ;), de laisser git les voir comme 'modifiés' et de les commiter, et d'en finir. Sinon, vous serez toujours harcelé par des messages ennuyeux ou des différences surprenantes, ou bien vous devrez désactiver toutes les fonctionnalités d'espacement de git.

Vous perdrez des informations sur le blâme, mais il est préférable de le faire le plus tôt possible :)

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