web-dev-qa-db-fra.com

git-diff à ignorer ^ M

Dans un projet où certains fichiers contiennent ^ M en tant que séparateurs de nouvelle ligne. Diffuser ces fichiers est apparemment impossible, car git-diff le voit comme le fichier entier n’est qu’une seule ligne.

Comment on diff avec la version précédente?

Existe-t-il une option du type "Traiter ^ M comme nouvelle ligne lors de la différenciation"?

Prompt> git-diff "HEAD^" -- MyFile.as 
diff --git a/myproject/MyFile.as b/myproject/MyFile.as
index be78321..a393ba3 100644
--- a/myproject/MyFile.cpp
+++ b/myproject/MyFile.cpp
@@ -1 +1 @@
-<U+FEFF>import flash.events.MouseEvent;^Mimport mx.controls.*;^Mimport mx.utils.Delegate
\ No newline at end of file
+<U+FEFF>import flash.events.MouseEvent;^Mimport mx.controls.*;^Mimport mx.utils.Delegate
\ No newline at end of file
Prompt>

MISE À JOUR:

maintenant, j'ai écrit un script qui extrait les 10 dernières révisions et convertit CR en LF.

require 'fileutils'

if ARGV.size != 3
  puts "a git-path must be provided"
  puts "a filename must be provided"
  puts "a result-dir must be provided"
  puts "example:"
  puts "Ruby gitcrdiff.rb project/dir1/dir2/dir3/ SomeFile.cpp tmp_somefile"
  exit(1)
end

gitpath = ARGV[0]
filename = ARGV[1]
resultdir = ARGV[2]

unless FileTest.exist?(".git")
  puts "this command must be run in the same dir as where .git resides"
  exit(1)
end

if FileTest.exist?(resultdir)
  puts "the result dir must not exist"
  exit(1)
end
FileUtils.mkdir(resultdir)

10.times do |i|
  revision = "^" * i
  cmd = "git show HEAD#{revision}:#{gitpath}#{filename} | tr '\\r' '\\n' > #{resultdir}/#{filename}_rev#{i}"
  puts cmd 
  system cmd
end
408
neoneye

GitHub suggère que vous devez vous assurer d’utiliser uniquement\n comme caractère de nouvelle ligne dans les dépôts gérés par git. Il y a une option pour convertir automatiquement:

$ git config --global core.autocrlf true

Bien sûr, on dit que ceci convertit crlf en lf, alors que vous voulez convertir cr en lf. J'espère que ça marche toujours…

Et convertissez ensuite vos fichiers:

# Remove everything from the index
$ git rm --cached -r .

# Re-add all the deleted files to the index
# You should get lots of messages like: "warning: CRLF will be replaced by LF in <file>."
$ git diff --cached --name-only -z | xargs -0 git add

# Commit
$ git commit -m "Fix CRLF"

core.autocrlf est décrit sur la page de manuel .

341
nes1983

Sous Windows, j'ai rencontré ce problème lorsque j'utilisais git tfs. Je l'ai résolu de cette façon:

git config --global core.whitespace cr-at-eol

En gros, cela indique à Git qu'un CR en fin de ligne n'est pas une erreur. Par conséquent, ces caractères ^M gênants n'apparaissent plus à la fin des lignes de git diff, git show, etc.

Il semble laisser les autres paramètres tels quels; par exemple, les espaces supplémentaires à la fin d'une ligne sont toujours affichés sous forme d'erreur (surlignés en rouge) dans le diff.

(D'autres réponses ont fait allusion à cela, mais la procédure ci-dessus indique exactement comment définir le paramètre. Pour définir le paramètre d'un seul projet, omettez le --global.)

EDIT:

Après de nombreux problèmes de fin de ligne, j'ai eu la meilleure chance de travailler avec une équipe .NET avec les paramètres suivants:

  • AUCUN réglage core.eol
  • NO core.whitespace setting
  • AUCUN paramètre core.autocrlf
  • Lorsque vous exécutez le programme d'installation Git pour Windows, vous obtenez les trois options suivantes:
    • Checkout style Windows, commettre des fins de ligne de style Unix <- choisissez celui-ci
    • Commander tel quel, commettre des fins de ligne de style Unix
    • Commander tel quel, commettre tel quel

Si vous devez utiliser le paramètre d'espacement, vous devez probablement l'activer uniquement projet par projet si vous devez interagir avec TFS. Oubliez simplement le --global:

git config core.whitespace cr-at-eol

Si vous devez supprimer certains paramètres de base. *, Le moyen le plus simple consiste à exécuter cette commande:

git config --global -e

Cela ouvre votre fichier global .gitconfig dans un éditeur de texte, et vous pouvez facilement supprimer les lignes que vous souhaitez supprimer. (Ou vous pouvez mettre '#' devant eux pour les commenter.)

332
Ryan Lundy

Essayez git diff --ignore-space-at-eol ou git diff --ignore-space-change ou git diff --ignore-all-space.

110
Jakub Narębski

Regarde aussi:

core.whitespace = cr-at-eol

ou équivalent,

[core]
    whitespace = cr-at-eol

whitespace est précédé d'un caractère tabulation.

100

Pourquoi obtenez-vous ces ^M dans votre git diff?

Dans mon cas, je travaillais sur un projet développé sous Windows et j'utilisais OS X. Lorsque j'ai modifié du code, j'ai vu ^M à la fin des lignes que j'avais ajoutées dans git diff. Je pense que les ^M apparaissaient car ils étaient des fins de lignes différentes du reste du fichier. Comme le reste du fichier a été développé sous Windows, il utilisait les fins de ligne CR et sous OS X, les fins de ligne LF.

Apparemment, le développeur Windows n’a pas utilisé l’option " Checkout dans le style Windows, valide les fins de ligne de style Unix " lors de l'installation de Git.

Alors, que devrions-nous faire à ce sujet?

Vous pouvez demander aux utilisateurs Windows de réinstaller git et d’utiliser l’option " Checkout style Windows, commettez les fins de ligne de style Unix ". C’est ce que je préférerais, car je vois Windows comme une exception dans ses caractères de fin de ligne et Windows corrige ainsi son propre problème.

Si vous optez pour cette option, vous devriez toutefois corriger les fichiers actuels (car ils utilisent toujours les fins de ligne CR). Je l'ai fait en suivant ces étapes:

  1. Supprimez tous les fichiers du référentiel, mais pas de votre système de fichiers.

    git rm --cached -r .
    
  2. Ajoutez un fichier .gitattributes qui oblige certains fichiers à utiliser un LF comme fin de ligne. Mettez ceci dans le fichier:

    *.ext text eol=crlf
    

    Remplacez .ext par les extensions de fichier que vous souhaitez faire correspondre.

  3. Ajoutez tous les fichiers à nouveau.

    git add .
    

    Cela affichera des messages comme ceci:

    warning: CRLF will be replaced by LF in <filename>.
    The file will have its original line endings in your working directory.
    
  4. Vous pouvez supprimer le fichier .gitattributes sauf si vous êtes un utilisateur Windows obstiné qui ne souhaite pas utiliser les fins de ligne " Checkout de style Windows, commit de style Unix "option.

  5. Engagez-vous et poussez tout.

  6. Supprimez et vérifiez les fichiers applicables sur tous les systèmes sur lesquels ils sont utilisés. Sur les systèmes Windows, assurez-vous qu'ils utilisent maintenant l'option " Checkout de style Windows, validez les fins de ligne de style Unix ". Vous devriez également le faire sur le système sur lequel vous avez exécuté ces tâches car lorsque vous avez ajouté les fichiers, git a déclaré:

    The file will have its original line endings in your working directory.
    

    Vous pouvez faire quelque chose comme ceci pour supprimer les fichiers:

    git ls | grep ".ext$" | xargs rm -f
    

    Et puis ceci pour les récupérer avec les fins de ligne correctes:

    git ls | grep ".ext$" | xargs git checkout
    

    Bien sûr, remplacer .ext avec l'extension de votre choix.

Votre projet utilise maintenant uniquement les caractères LF pour les fins de ligne, et les vicieux caractères CR ne reviendront jamais :).

L'autre option consiste à appliquer des fins de ligne de style Windows. Vous pouvez également utiliser le fichier .gitattributes pour cela.

Plus d'infos: https://help.github.com/articles/dealing-with-line-endings/#platform-all

38
gitaarik

Existe-t-il une option du type "Traiter ^ M comme nouvelle ligne lors de la différenciation"?

Il y en aura une avec Git 2.16 (T1 2018), en tant que famille de commandes "diff" apprises à ignorer les différences de retour chariot en fin de ligne.

Voir commit e9282f (26 octobre 2017) par Junio ​​C Hamano (gitster) .
Aidé par: Johannes Schindelin (dscho) .
(Fusionné par Junio ​​C Hamano - gitster - dans commit 10f65c2 , 27 nov. 2017)

diff: _--ignore-cr-at-eol_

Une nouvelle option --ignore-cr-at-eol indique à la machine diff de traiter un retour chariot à la fin d'une ligne (complète) comme si ce n'était pas le cas. exister.

Tout comme les autres options "_--ignore-*_" pour ignorer divers types de différences d'espaces, ceci vous aidera à réviser les véritables changements que vous avez effectués sans vous laisser distraire par la fausse conversion _CRLF<->LF_ effectuée par votre programme d'édition.

29
VonC

TL; DR

Changez le _core.pager_ en _"tr -d '\r' | less -REX"_, pas le code source

C'est pourquoi

Ces embêtants sont un artefact de la colorisation et du téléavertisseur. enter image description here Ceci est causé par _less -R_, une option de paginateur git par défaut. (Le pagineur par défaut de Git est less -REX )

La première chose à noter est que git diff -b n’indiquera pas les modifications de l’espace blanc (par exemple, le\r\n vs\n)

installer:

_git clone https://github.com/CipherShed/CipherShed
cd CipherShed
_

Un test rapide pour créer un fichier Unix et modifier les fins de ligne n’indiquera aucune modification avec _git diff -b_:

_echo -e 'The quick brown fox\njumped over the lazy\ndogs.' > test.txt
git add test.txt
unix2dos.exe test.txt
git diff -b test.txt
_

Nous notons que forcer un tuyau à moins ne montre pas le ^ M, mais l'activation de la couleur et _less -R_ fait:

_git diff Origin/v0.7.4.0 Origin/v0.7.4.1 | less
git -c color.ui=always diff Origin/v0.7.4.0 Origin/v0.7.4.1 | less -R
_

Le correctif est affiché en utilisant un tuyau pour extraire le\r (^ M) de la sortie:

_git diff Origin/v0.7.4.0 Origin/v0.7.4.1
git -c core.pager="tr -d '\r' | less -REX"  diff Origin/v0.7.4.0 Origin/v0.7.4.1
_

Une alternative peu judicieuse consiste à utiliser _less -r_, car il transitera tous les codes de contrôle, pas seulement les codes de couleur.

Si vous voulez simplement éditer votre fichier de configuration git directement, voici l’entrée à mettre à jour/ajouter:

_[core]
        pager = tr -d '\\r' | less -REX
_
19
Jason Pyeron

J'ai longtemps lutté contre ce problème. De loin, la solution la plus simple est de ne pas s’inquiéter des caractères ^ M et d’utiliser un outil de différenciation visuel capable de les gérer.

Au lieu de taper:

git diff <commitHash> <filename>

essayer:

git difftool <commitHash> <filename>
13
Ian Wojtowicz

Si vous utilisez Eclipse, vous pouvez supprimer le ^M de git diff en définissant File > Convert Line Delimiter To > Unix (LF, \n, 0A, ¶)

0
Adil