git-diff忽略^ M

在某些文件中包含^ M作为换行符分隔符的项目中。 区分这些文件显然是不可能的,因为git-diff将整个文件视为一行。

如何与以前的版本不同?

有没有这样的选项,如“在处理时将^ M作为换行符”?

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> 

更新:

现在我已经写了一个脚本,检查出最新的10个修订版本,并将CR转换为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 

GitHubbuild议你应该确保只使用\ n作为git处理仓库中的换行符。 有一个选项可以自动转换:

 $ git config --global core.autocrlf true 

当然,据说将crlf转换为lf,而你想将cr转换为lf。 我希望这仍然有效…

然后转换你的文件:

 # 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 在手册页描述。

在Windows上开发,我使用git tfs时遇到了这个问题。 我这样解决了它:

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

这基本上告诉Git一个行尾CR是不是一个错误。 结果,那些烦人的^M字符不再出现在git diffgit show等行的末尾

它似乎离开其他设置原样; 例如,行末尾的额外空格在diff中仍然显示为错误(以红色突出显示)。

(其他答案也有提及,但上面的内容正是如何设置的,要设置只有一个项目的设置,可以省略--global 。)

编辑

在经历了许多结束的难题之后,在.NET团队工作时,我有了最好的运气,

  • 没有core.eol设置
  • 没有core.whitespace设置
  • 没有core.autocrlf设置
  • 运行Windows的Git安装程序时,您将得到以下三个选项:
    • 签出Windows风格,提交Unix风格的行结尾 < – select这一个
    • 按原样签出,提交Unix风格的行结尾
    • 按原样签出,按原样提交

如果您需要使用空格设置,则应该只在每个项目的基础上启用它,如果您需要与TFS交互。 只要省略--global

 git config core.whitespace cr-at-eol 

如果你需要删除一些核心。*设置,最简单的方法是运行这个命令:

 git config --global -e 

这将在文本编辑器中打开您的全局.gitconfig文件,您可以轻松地删除要删除的行。 (或者你可以把“#”放在他们面前来评论他们。)

另请参阅:

 core.whitespace = cr-at-eol 

或者等同地,

 [core] whitespace = cr-at-eol 

whitespace前面有一个制表符。

试试git diff --ignore-space-at-eol ,或者git diff --ignore-space-change ,或者git diff --ignore-all-space

你为什么在你的git diff获得这些^M

在我的情况下,我正在开发一个在Windows中开发的项目,并且使用了OS X.当我更改了一些代码时,我在git diff添加的行的末尾看到了^M 我觉得^M显示出来了,因为它们是不同于文件其他部分的结尾。 因为文件的其余部分是在Windows中开发的,所以它使用CR行结束符,在OS X中它使用LF行结束符。

显然,Windows开发者在安装Git的时候并没有使用“ Checkout Windows风格,提交Unix风格的行结尾 ”选项。

那么我们应该怎么做呢?

你可以让Windows用户重新安装git并使用“ Checkout Windows风格,提交Unix风格的行尾 ”选项。 这是我更喜欢的,因为我认为Windows是行结束字符的exception,Windows通过这种方式修复了它自己的问题。

如果您select此选项,则应该修复当前文件(因为它们仍然使用CR行尾)。 我通过以下步骤做到了这一点:

  1. 从存储库中删除所有文件,但不从文件系统中删除。

     git rm --cached -r . 
  2. 添加一个强制执行某些文件的.gitattributes文件,以使用LF作为行尾。 把这个放在文件中:

     *.ext text eol=crlf 

    .extreplace为您要匹配的文件扩展名。

  3. 再次添加所有文件。

     git add . 

    这将显示这样的消息:

     warning: CRLF will be replaced by LF in <filename>. The file will have its original line endings in your working directory. 
  4. 您可以删除.gitattributes文件,除非您有顽固的Windows用户不想使用“ 签出Windows风格,提交Unix风格的行结束 ”选项。

  5. 承诺并推动一切。

  6. 删除并检出使用的所有系统上的适用文件。 在Windows系统上,确保他们现在使用“ Checkout Windows风格,提交Unix风格的行尾 ”选项。 你也应该在你执行这些任务的系统上这样做,因为当你添加文件git时说:

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

    你可以这样做来删除文件:

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

    然后这个让他们回到正确的行结尾:

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

    当然用你想要的扩展replace.ext

现在你的项目只使用LF字符作为行尾,而令人讨厌的CR字符不会再回来:)。

另一种select是强制执行窗口样式行尾。 您也可以使用.gitattributes文件。

更多信息: https : //help.github.com/articles/dealing-with-line-endings/#platform-all

我长期以来一直在努力解决这个问题。 到目前为止,最简单的解决scheme是不用担心^ M字符,只是使用一个可以处理它们的视觉差异工具。

而不是打字:

 git diff <commitHash> <filename> 

尝试:

 git difftool <commitHash> <filename> 

TL; DR

core.pager更改为"tr -d '\r' | less -REX" ,而不是源代码

这就是为什么

显示的那些烦人的^ M是彩色化和寻呼机的伪像。 在这里输入图像描述 这是由less -R引起的,默认的git pager选项。 (git的默认寻呼机less -REX

首先要注意的是, git diff -b不会显示空白处的变化(例如\ r \ n vs \ n)

build立:

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

创build一个unix文件并更改行尾的快速testing将不会显示使用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 

我们注意到,迫使一个pipe道较less不显示^ M,但使颜色和less -R确实:

 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 

通过使用pipe道从输出中去除\ r(^ M)来显示修复:

 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 

不明智的select是使用less -r ,因为它将通过所有的控制代码,而不仅仅是颜色代码。

如果你想直接编辑你的gitconfiguration文件,这是更新/添加条目:

 [core] pager = tr -d '\\r' | less -REX 

如果你正在使用Eclipse,你可以通过设置File > Convert Line Delimiter To > Unix (LF, \n, 0A, ¶)使^Mgit diff消失。