git-diff忽略^ M.

时间:2009-12-11 17:23:49

标签: git diff newline git-diff

在某个项目中,某些文件包含^ 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

11 个答案:

答案 0 :(得分:316)

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

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

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

似乎按原样保留其他设置;例如,一行末尾的额外空格仍显示为差异中的错误(以红色突出显示)。

(其他答案已经提到了这一点,但以上就是如何设置设置。要仅设置一个项目的设置,请省略--global。)

修改

在经历了许多线路结束后,我在使用这些设置时在.NET团队工作时运气最好:

  • 没有core.eol设置
  • 没有core.whitespace设置
  • 没有core.autocrlf设置
  • 运行Windows的Git安装程序时,您将获得以下三个选项:
    • Checkout Windows风格,提交Unix风格的行结尾&lt; - 选择此一个
    • 按原样结帐,提交Unix风格的行结尾
    • 按原样结帐,按原样提交

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

即可
git config core.whitespace cr-at-eol

如果您需要删除某些核心。*设置,最简单的方法是运行此命令:

git config --global -e

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

答案 1 :(得分:315)

GitHub suggests你应该确保只使用\ n作为git-handling repos中的换行符。有一个自动转换选项:

$ 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在the man page上进行了描述。

答案 2 :(得分:108)

尝试git diff --ignore-space-at-eolgit diff --ignore-space-changegit diff --ignore-all-space

答案 3 :(得分:95)

另见:

core.whitespace = cr-at-eol

或等效,

[core]
    whitespace = cr-at-eol

其中whitespace前面有标签字符。

答案 4 :(得分:38)

为什么在^M

中获得这些git diff

在我的情况下,我正在开发一个在Windows中开发的项目,我使用的是OS X.当我更改了一些代码时,我在^M中添加的行的末尾看到了git diff 。我认为^M出现了,因为它们的行结尾与文件的其余部分不同。由于文件的其余部分是在Windows中开发的,因此使用CR行结尾,而在OS X中,它使用LF行结尾。

显然,Windows开发人员并没有使用&#34; Checkout Windows风格,提交Unix风格的行结尾&#34;在安装Git期间。

那我们该怎么做呢?

您可以让Windows用户重新安装git并使用&#34; Checkout Windows风格,提交Unix风格的行结尾&#34;选项。这是我更喜欢的,因为我认为Windows是一个例外,它的行结尾字符和Windows修复了它自己的问题。

如果您选择此选项,则应修复当前文件(因为它们仍然使用CR行结尾)。我是按照以下步骤完成的:

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

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

    *.ext text eol=crlf
    

    .ext替换为您要匹配的文件扩展名。

  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用户不想使用&#34; Checkout Windows样式,提交Unix样式的行结尾&#34;选项。

  5. 提交并推送所有内容。

  6. 删除并签出他们所使用的所有系统上的适用文件。在Windows系统上,确保它们现在使用&#34; Checkout Windows样式,提交Unix样式的行结尾&#34;选项。您还应该在执行这些任务的系统上执行此操作,因为当您添加文件时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
    

    当然用您想要的扩展程序替换.ext

  7. 现在,您的项目仅使用LF字符作为行结尾,并且令人讨厌的CR字符不会再回来:)。

    另一种选择是强制执行Windows样式行结尾。您也可以使用.gitattributes文件。

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

答案 5 :(得分:23)

  

是否存在类似&#34;选项时将^ M视为换行符#34; ?

将有一个Git 2.16(2018年第一季度),作为&#34; diff&#34;一系列命令学会忽略行末回车的差异。

commit e9282f0Junio C Hamano (gitster)(2017年10月26日) 帮助:Johannes Schindelin (dscho)
Junio C Hamano -- gitster --于2017年11月27日commit 10f65c2合并)

  

diff:--ignore-cr-at-eol

     

新选项 --ignore-cr-at-eol 告诉diff机器在(完整)行的末尾处理回车符,就像它不存在一样。

     

就像其他&#34; --ignore-*&#34;忽略各种空白差异的选项,这有助于审核您所做的真正更改,而不会被编辑程序进行的虚假CRLF<->LF转换分散注意力。

答案 6 :(得分:15)

<强> TL; DR

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

这就是为什么

显示的那些讨厌的^ M是着色和寻呼机的人工制品。 enter image description here 它是由less -R引起的,这是一个默认的git pager选项。 (git的默认寻呼机为less -REX

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

设置:

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

创建unix文件并更改行结尾的快速测试将不会显示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

我们注意到强制管道减少不会显示^ 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

通过使用管道从输出中剥离\ 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

一个不明智的选择是使用less -r,因为它会传递所有控制代码,而不仅仅是颜色代码。

如果您想直接编辑您的git配置文件,这是更新/添加的条目:

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

答案 7 :(得分:13)

我很长时间都在努力解决这个问题。到目前为止,最简单的解决方案是不要担心^ M字符,只需使用可以处理它们的视觉差异工具。

而不是输入:

git diff <commitHash> <filename>

尝试:

git difftool <commitHash> <filename>

答案 8 :(得分:8)

就我而言,这是什么命令:

git config  core.whitespace cr-at-eol

来源:https://public-inbox.org/git/8d7e4807-9a79-e357-8265-95f22ab716e0@web.de/T/

答案 9 :(得分:1)

正如VonC所指出的,它已经包含在git 2.16+中。不幸的是,选项(--ignore-cr-at-eol)的名称与我以前习惯的(--strip-trailing-cr)使用的GNU diff的名称不同。

当我遇到这个问题时,我的解决方案是调用GNU diff而不是git的内置diff,因为我的git早于2.16。我是使用以下命令行完成的:

GIT_EXTERNAL_DIFF='diff -u --strip-trailing-cr "$2" "$5";true;#' git diff --ext-diff

这允许使用--strip-trailing-cr和任何其他GNU diff选项。

还有另一种方式:

git difftool -y -x 'diff -u --strip-trailing-cr'

但是它不使用配置的寻呼机设置,这就是为什么我更喜欢前者。

答案 10 :(得分:0)

如果您使用的是Eclipse,则可以通过设置^M

使git diffFile > Convert Line Delimiter To > Unix (LF, \n, 0A, ¶)消失