git-diff à ignorer ^M

dans un projet où certains fichiers contiennent des séparateurs newline. La diffusion de ces fichiers est apparemment impossible, puisque git-diff le voit comme le fichier entier n'est qu'une seule ligne.

quelle différence y a-t-il avec la version précédente?

y a-t-il une option Comme "traiter ^M comme newline lors de la diffusion" ?

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 vérifie 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
337
demandé sur RzR 2009-12-11 20:23:49

9 réponses

GitHub suggère que vous devez vous assurer de n'utiliser \n qu'en tant que caractère newline dans les repos git-handled. Il y a une option pour auto-convertir:

$ git config --global core.autocrlf true

bien sûr, on dit que cela convertit crlf en lf, alors que vous voulez convertir cr en LF. J'espère que cela fonctionne encore ...

et puis convertir 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"

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

275
répondu nes1983 2015-12-17 15:39:37

développé sur Windows, j'ai rencontré ce problème en utilisant git tfs . Je l'ai résolu de cette façon:

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

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

il semble laisser les autres paramètres comme-est; par exemple, les espaces supplémentaires à la fin d'une ligne montrent encore comme des erreurs (en surbrillance en rouge) dans la diff.

(D'autres réponses ont fait allusion à cela, mais ce qui précède est exactement comment définir le cadre. Pour définir le cadre d'un seul projet, omettez le --global .)

MODIFIER :

après de nombreux labeurs de fin de ligne, j'ai eu la meilleure chance, en travaillant sur une équipe .NET, avec ces paramètres:

  • PAS de noyau.eol paramètre
  • PAS de core.réglage de l'espace blanc
  • PAS de noyau.réglage autocrlf
  • lors de L'exécution de l'installateur Git pour Windows, vous aurez ces trois options:
    • Caisse de style Windows, commettre de style Unix, les fins de ligne <-- choisir celui-ci
    • passer à la Caisse, s'engager de style Unix, les fins de ligne
    • passer à la Caisse, s'engager en tant qu'-est

si vous devez utiliser le paramètre espace, vous devriez probablement l'activer seulement par projet si vous avez besoin d'interagir avec TFS. Il suffit d'omettre le --global :

git config core.whitespace cr-at-eol

si vous avez besoin d'enlever un noyau.* les paramètres, le plus simple est d'exécuter cette commande:

git config --global -e

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

271
répondu Ryan Lundy 2012-04-02 20:57:54

Try git diff --ignore-space-at-eol , ou git diff --ignore-space-change , ou git diff --ignore-all-space .

102
répondu Jakub Narębski 2009-12-11 18:19:56

Voir aussi:

core.whitespace = cr-at-eol

ou l'équivalent,

[core]
    whitespace = cr-at-eol

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

90
répondu Vladimir Panteleev 2015-02-27 03:07:33

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

dans mon cas, je travaillais sur un projet qui a été développé dans Windows et J'ai utilisé OS X. Lorsque j'ai changé quelque code, j'ai vu ^M à la fin des lignes que j'ai ajouté dans git diff . Je pense que le ^M est apparu parce qu'ils étaient des fins de ligne différentes que le reste du dossier. Parce que le reste du fichier a été développé dans Windows il a utilisé CR fin de ligne, et dans OS X il utilise les fins de ligne LF .

apparemment, le développeur Windows n'a pas utilisé l'option " Checkout Windows-style, commit Unix-style fin de ligne " lors de l'installation de git.

alors que faire?

vous pouvez faire réinstaller git par les utilisateurs de Windows et utiliser L'option " " Checkout Windows-style, commit Unix-style line endings ". C'est ce que je je préférerais, parce que je vois Windows comme une exception dans ses caractères de fin de ligne et Windows corrige son propre problème de cette façon.

si vous optez pour cette option, vous devez cependant corriger les fichiers courants (parce qu'ils utilisent toujours la fin de la ligne CR ). Je l'ai fait en suivant ces étapes:

  1. supprimez tous les fichiers du dépôt, mais pas de votre système de fichiers.

    git rm --cached -r .
    
  2. Ajouter un .gitattributes fichier applique à certains fichiers pour utiliser un LF que les fins de ligne. Mettez ceci dans le fichier:

    *.ext text eol=crlf
    

    remplacer .ext par les extensions de fichier que vous souhaitez associer.

  3. Ajouter tous les fichiers à nouveau.

    git add .
    

    ceci montrera 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 pourriez supprimer le .gitattributes fichier à moins que vous n'ayez des utilisateurs de Windows têtus qui ne veulent pas utiliser le " Checkout Windows-style, commit Unix-style fin de ligne " option.

  5. engagez-vous et poussez-le.

  6. supprimer et vérifier les fichiers pertinents sur tous les systèmes où ils sont utilisés. Sur les systèmes de fenêtres, assurez-vous qu'ils utilisent maintenant le" Caisse Windows-style, fin de ligne de type Unix " option. Vous devriez également le faire sur le système où vous avez exécuté ces tâches parce que lorsque vous avez ajouté les fichiers git dit:

    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 par l'extension que vous voulez.

maintenant votre projet utilise seulement LF caractères pour les terminaisons de ligne, et le méchant CR caractères ne reviendra jamais :).

l'autre option est d'appliquer les fins de ligne de style windows. Vous pouvez également utiliser le fichier .gitattributes pour cela.

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

31
répondu gitaarik 2016-12-20 16:36:10

y a-t-il une option Comme "traiter ^M comme newline lors de la diffusion" ?

il y en aura un avec Git 2.16 (Q1 2018), comme la " diff " famille de commandes a appris à ignorer les différences de retour de chariot à la fin de la ligne.

Voir commettre e9282f0 (26 Oct 2017) par Junio C Hamano ( gitster ) .

Aidé par: Johannes Schindelin ( dscho ) .

(fusionné par Junio CA Hamano -- gitster -- in commit 10f65c2 , 27 Nov 2017)

diff: --ignore-cr-at-eol

une nouvelle option --ignore-cr-at-eol dit à la machine diff de traiter un chariot-retour à la fin d'une ligne (complète) comme si elle ne exister.

comme les autres" --ignore-* " options pour ignorer les différences d'espace, cela aidera à passer en revue les changements réels que vous avez faits sans se laisser distraire par la conversion CRLF<->LF faux fait par votre programme d'éditeur.

14
répondu VonC 2018-05-15 11:03:24

TL; DR

changer le core.pager en "tr -d '\r' | less -REX" , pas le code source

C'est pourquoi

ceux pesky ^M montrés sont un artefact de la colorisation et le pager. enter image description here Il est causé par less -R , une option de pager git par défaut. (le pager par défaut de git est less -REX )

la première chose à noter est que git diff -b ne montrera pas de changements dans l'espace blanc (par exemple le \r\n vs \n)

installation:

git clone https://github.com/CipherShed/CipherShed
cd CipherShed

un test rapide pour créer un fichier unix et changer les fins de ligne ne montrera aucun changement 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 permet la couleur et less -R ne:

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 repère est montré en utilisant un tuyau pour retirer 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 imprudente est d'utiliser less -r , car il passera à travers tous les codes de contrôle, pas seulement les codes de couleur.

si vous voulez simplement modifier votre fichier de configuration git directement, il s'agit de l'entrée pour mettre à jour/ajouter:

[core]
        pager = tr -d '\r' | less -REX
11
répondu Jason Pyeron 2017-09-17 14:19:36

j'ai lutté avec ce problème pendant une longue période. La solution de loin la plus simple est de ne pas se soucier des caractères ^M et d'utiliser simplement un outil de diff visuel qui peut les manipuler.

au lieu de:

git diff <commitHash> <filename>

, essayez:

git difftool <commitHash> <filename>
10
répondu Ian Wojtowicz 2011-08-16 04:10:44

si vous utilisez Eclipse, vous pouvez faire disparaître le ^M de git diff en paramétrant File > Convert Line Delimiter To > Unix (LF, \n, 0A, ¶)

0
répondu Adil 2015-12-04 13:48:08