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 diff
, git 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
行尾)。 我通过以下步骤做到了这一点:
-
从存储库中删除所有文件,但不从文件系统中删除。
git rm --cached -r .
-
添加一个强制执行某些文件的
.gitattributes
文件,以使用LF
作为行尾。 把这个放在文件中:*.ext text eol=crlf
将
.ext
replace为您要匹配的文件扩展名。 -
再次添加所有文件。
git add .
这将显示这样的消息:
warning: CRLF will be replaced by LF in <filename>. The file will have its original line endings in your working directory.
-
您可以删除
.gitattributes
文件,除非您有顽固的Windows用户不想使用“ 签出Windows风格,提交Unix风格的行结束 ”选项。 -
承诺并推动一切。
-
删除并检出使用的所有系统上的适用文件。 在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, ¶)
使^M
从git diff
消失。