git-diff 忽略 ^M
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1889559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
git-diff to ignore ^M
提问by neoneye
In a project where some of the files contains ^M as newline separators. Diffing these files are apparently impossible, since git-diff sees it as the entire file is just a single line.
在某些文件包含 ^M 作为换行符的项目中。区分这些文件显然是不可能的,因为 git-diff 认为整个文件只是一行。
How does one diff with the previous version?
一个与以前的版本有何不同?
Is there an option like "treat ^M as newline when diffing" ?
是否有“将 ^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>
UPDATE:
更新:
now I have written a Ruby script that checks out the latest 10 revisions and converts CR to LF.
现在我已经编写了一个 Ruby 脚本来检查最新的 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
采纳答案by nes1983
GitHub suggeststhat you should make sure to only use \n as a newline character in git-handled repos. There's an option to auto-convert:
GitHub 建议你应该确保在 git-handled repos 中只使用 \n 作为换行符。有一个选项可以自动转换:
$ git config --global core.autocrlf true
Of course, this is said to convert crlf to lf, while you want to convert cr to lf. I hope this still works …
当然,这个是说把crlf转为lf,而你想把cr转为lf。我希望这仍然有效……
And then convert your files:
然后转换您的文件:
# 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 is described on the man page.
core.autocrlf在手册页中有描述。
回答by Ryan Lundy
Developing on Windows, I ran into this problem when using git tfs
. I solved it this way:
在 Windows 上开发,我在使用git tfs
. 我是这样解决的:
git config --global core.whitespace cr-at-eol
This basically tells Git that an end-of-line CR is not an error. As a result, those annoying ^M
characters no longer appear at the end of lines in git diff
, git show
, etc.
这基本上告诉 Git 行尾 CR 不是错误。其结果是,那些烦人的^M
字符不再出现在线路末端git diff
,git show
等等。
It appears to leave other settings as-is; for instance, extra spaces at the end of a line still show as errors (highlighted in red) in the diff.
其他设置似乎保持原样;例如,行尾的额外空格仍会在差异中显示为错误(以红色突出显示)。
(Other answers have alluded to this, but the above is exactly how to set the setting. To set the setting for only one project, omit the --global
.)
(其他答案已经提到了这一点,但上面正是如何设置设置。要仅为一个项目设置设置,请省略--global
.)
EDIT:
编辑:
After many line-ending travails, I've had the best luck, when working on a .NET team, with these settings:
在经历了许多行结束的痛苦之后,我在 .NET 团队中工作时运气最好,使用以下设置:
- NO core.eol setting
- NO core.whitespace setting
- NO core.autocrlf setting
- When running the Git installer for Windows, you'll get these three options:
- Checkout Windows-style, commit Unix-style line endings<-- choose this one
- Checkout as-is, commit Unix-style line endings
- Checkout as-is, commit as-is
- 没有 core.eol 设置
- 没有 core.whitespace 设置
- 没有 core.autocrlf 设置
- 运行适用于 Windows 的 Git 安装程序时,您将获得以下三个选项:
- 签出 Windows 风格,提交 Unix 风格的行尾<-- 选择这个
- 按原样结帐,提交 Unix 样式的行结尾
- 按原样结帐,按原样提交
If you need to use the whitespace setting, you should probably enable it only on a per-project basis if you need to interact with TFS. Just omit the --global
:
如果您需要使用空白设置,并且您需要与 TFS 交互时,您可能应该仅在每个项目的基础上启用它。只需省略--global
:
git config core.whitespace cr-at-eol
If you need to remove some core.* settings, the easiest way is to run this command:
如果您需要删除某些 core.* 设置,最简单的方法是运行以下命令:
git config --global -e
This opens your global .gitconfig file in a text editor, and you can easily delete the lines you want to remove. (Or you can put '#' in front of them to comment them out.)
这将在文本编辑器中打开您的全局 .gitconfig 文件,您可以轻松删除要删除的行。(或者您可以在它们前面加上“#”以将它们注释掉。)
回答by Jakub Nar?bski
Try git diff --ignore-space-at-eol
, or git diff --ignore-space-change
, or git diff --ignore-all-space
.
试试git diff --ignore-space-at-eol
、 或git diff --ignore-space-change
、 或git diff --ignore-all-space
。
回答by Vladimir Panteleev
Also see:
另见:
core.whitespace = cr-at-eol
or equivalently,
或等效地,
[core]
whitespace = cr-at-eol
where whitespace
is preceded by a tabcharacter.
wherewhitespace
前面是制表符。
回答by gitaarik
Why do you get these ^M
in your git diff
?
你为什么把这些^M
放在你的git diff
?
In my case I was working on a project which was developed in Windows and I used OS X. When I changed some code, I saw ^M
at the end of the lines I added in git diff
. I think the ^M
were showing up because they were different line endings than the rest of the file. Because the rest of the file was developed in Windows it used CR
line endings, and in OS X it uses LF
line endings.
就我而言,我正在处理一个在 Windows 中开发的项目,我使用的是 OS X。当我更改一些代码时,我看到^M
在git diff
. 我认为^M
它们之所以出现是因为它们的行尾与文件的其余部分不同。因为文件的其余部分是在 Windows 中开发的,所以它使用CR
行尾,而在 OS X 中它使用LF
行尾。
Apparently, the Windows developer didn't use the option "Checkout Windows-style, commit Unix-style line endings" during the installation of Git.
显然,Windows 开发人员在安装 Git 期间没有使用选项“ Checkout Windows-style, commit Unix-style lineendings”。
So what should we do about this?
那么我们应该怎么做呢?
You can have the Windows users reinstall git and use the "Checkout Windows-style, commit Unix-style line endings" option. This is what I would prefer, because I see Windows as an exception in its line ending characters and Windows fixes its own issue this way.
您可以让 Windows 用户重新安装 git 并使用“ Checkout Windows-style, commit Unix-style lineendings”选项。这是我更喜欢的,因为我将 Windows 视为其行尾字符的例外,而 Windows 以这种方式修复了自己的问题。
If you go for this option, you should however fix the current files (because they're still using the CR
line endings). I did this by following these steps:
如果您选择此选项,则应该修复当前文件(因为它们仍在使用CR
行尾)。我按照以下步骤完成了此操作:
Remove all files from the repository, but not from your filesystem.
git rm --cached -r .
Add a
.gitattributes
file that enforces certain files to use aLF
as line endings. Put this in the file:*.ext text eol=crlf
Replace
.ext
with the file extensions you want to match.Add all the files again.
git add .
This will show messages like this:
warning: CRLF will be replaced by LF in <filename>. The file will have its original line endings in your working directory.
You could remove the
.gitattributes
file unless you have stubborn Windows users that don't want to use the "Checkout Windows-style, commit Unix-style line endings" option.Commit and push it all.
Remove and checkout the applicable files on all the systems where they're used. On the Windows systems, make sure they now use the "Checkout Windows-style, commit Unix-style line endings" option. You should also do this on the system where you executed these tasks because when you added the files git said:
The file will have its original line endings in your working directory.
You can do something like this to remove the files:
git ls | grep ".ext$" | xargs rm -f
And then this to get them back with the correct line endings:
git ls | grep ".ext$" | xargs git checkout
Of course replacing
.ext
with the extension you want.
从存储库中删除所有文件,但不从文件系统中删除。
git rm --cached -r .
添加
.gitattributes
强制某些文件使用 aLF
作为行结尾的文件。把它放在文件中:*.ext text eol=crlf
替换
.ext
为您要匹配的文件扩展名。再次添加所有文件。
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 用户不想使用“ Checkout Windows 风格,提交 Unix 风格行尾”选项。承诺并推动这一切。
删除并签出所有使用它们的系统上的适用文件。在 Windows 系统上,确保他们现在使用“ Checkout Windows-style, commit Unix-style lineendings”选项。您还应该在执行这些任务的系统上执行此操作,因为在添加文件时 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
你想要的扩展名替换。
Now your project only uses LF
characters for the line endings, and the nasty CR
characters won't ever come back :).
现在你的项目只使用LF
字符作为行尾,讨厌的CR
字符永远不会回来:)。
The other option is to enforce windows style line endings. You can also use the .gitattributes
file for this.
另一种选择是强制使用 Windows 样式的行尾。您也可以.gitattributes
为此使用该文件。
More info: https://help.github.com/articles/dealing-with-line-endings/#platform-all
更多信息:https: //help.github.com/articles/dealing-with-line-endings/#platform-all
回答by VonC
Is there an option like "treat ^M as newline when diffing" ?
是否有“将 ^M 视为换行符”之类的选项?
There will be one with Git 2.16 (Q1 2018), as the "diff
" family of commands learned to ignore differences in carriage return at the end of line.
Git 2.16(2018 年第一季度)将有一个,因为“ diff
”命令系列学会了忽略行尾回车符的差异。
See commit e9282f0(26 Oct 2017) by Junio C Hamano (gitster
).
Helped-by: Johannes Schindelin (dscho
).
(Merged by Junio C Hamano -- gitster
--in commit 10f65c2, 27 Nov 2017)
请参阅Junio C Hamano() 的提交 e9282f0(2017 年 10 月 26 日)。
帮助者:约翰内斯·辛德林 ( )。(由Junio C Hamano合并-- --在commit 10f65c2,2017 年 11 月 27 日)gitster
dscho
gitster
diff:
--ignore-cr-at-eol
A new option
--ignore-cr-at-eol
tells the diff machinery to treat a carriage-return at the end of a (complete) line as if it does not exist.Just like other "
--ignore-*
" options to ignore various kinds of whitespace differences, this will help reviewing the real changes you made without getting distracted by spuriousCRLF<->LF
conversion made by your editor program.
差异:
--ignore-cr-at-eol
一个新选项
--ignore-cr-at-eol
告诉 diff 机制将(完整)行末尾的回车视为不存在。就像
--ignore-*
忽略各种空白差异的其他“ ”选项一样,这将有助于查看您所做的真实更改,而不会被CRLF<->LF
编辑器程序所做的虚假转换分心。
回答by Jason Pyeron
TL;DR
TL; 博士
Change the core.pager
to "tr -d '\r' | less -REX"
, not the source code
更改core.pager
为"tr -d '\r' | less -REX"
,而不是源代码
This is why
这就是为什么
Those pesky ^M shown are an artifact of the colorization and the pager. It is caused by
less -R
, a default git pager option. (git's default pager is less -REX
)
显示的那些讨厌的 ^M 是着色和寻呼机的产物。它是由
less -R
默认的 git pager 选项引起的。(git 的默认寻呼机是less -REX
)
The first thing to note is that git diff -b
will not show changes in white space (e.g. the \r\n vs \n)
首先要注意的是git diff -b
不会显示空白处的变化(例如\r\n vs \n)
setup:
设置:
git clone https://github.com/CipherShed/CipherShed
cd CipherShed
A quick test to create a unix file and change the line endings will show no changes with git diff -b
:
创建 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
We note that forcing a pipe to less does not show the ^M, but enabling color and less -R
does:
我们注意到强制管道减少不会显示 ^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
The fix is shown by using a pipe to strip the \r (^M) from the output:
通过使用管道从输出中去除 \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
An unwise alternative is to use less -r
, because it will pass through all control codes, not just the color codes.
一个不明智的选择是使用less -r
,因为它将通过所有控制代码,而不仅仅是颜色代码。
If you want to just edit your git config file directly, this is the entry to update/add:
如果你只想直接编辑你的 git 配置文件,这是更新/添加的条目:
[core]
pager = tr -d '\r' | less -REX
回答by Ian Wojtowicz
I struggled with this problem for a long time. By far the easiest solution is to not worry about the ^M characters and just use a visual diff tool that can handle them.
我在这个问题上挣扎了很长时间。到目前为止,最简单的解决方案是不用担心 ^M 字符,只需使用可以处理它们的视觉差异工具。
Instead of typing:
而不是键入:
git diff <commitHash> <filename>
try:
尝试:
git difftool <commitHash> <filename>
回答by alesub
In my case, what did it was this command:
就我而言,这是什么命令:
git config core.whitespace cr-at-eol
回答by Pedro Gimeno
As noted by VonC, this has already been included in git 2.16+. Unfortunately, the name of the option (--ignore-cr-at-eol
) differs from the one used by GNU diff that I'm used to (--strip-trailing-cr
).
正如 VonC 所指出的,这已经包含在 git 2.16+ 中。不幸的是,选项 ( --ignore-cr-at-eol
)的名称与我习惯的 GNU diff 使用的名称 ( ) 不同--strip-trailing-cr
。
When I was confronted with this problem, my solution was to invoke GNU diff instead of git's built-in diff, because my git is older than 2.16. I did that using this command line:
当我遇到这个问题时,我的解决方案是调用GNU diff而不是git的内置diff,因为我的git是2.16以上的。我是用这个命令行做到的:
GIT_EXTERNAL_DIFF='diff -u --strip-trailing-cr "" "";true;#' git diff --ext-diff
That allows using --strip-trailing-cr
and any other GNU diff options.
这允许使用--strip-trailing-cr
和任何其他 GNU 差异选项。
There's also this other way:
还有另一种方式:
git difftool -y -x 'diff -u --strip-trailing-cr'
but it doesn't use the configured pager settings, which is why I prefer the former.
但它不使用配置的寻呼机设置,这就是我更喜欢前者的原因。