在某些文件包含 ^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>
更新:
现在我已经编写了一个 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
git diff -b
- 我在 stackoverflow.com/a/46265081/58794 中展示过
git diff --ignore-cr-at-eol
。请参阅my answer below。
git diff -b
与 git diff --ignore-space-change
相同。
dos2unix
(和 unix2dos
)在行尾之间进行转换。
GitHub suggests 你应该确保在 git-handled repos 中只使用 \n 作为换行符。有一个自动转换的选项:
$ 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 上进行了描述。
在 Windows 上开发,我在使用 git tfs
时遇到了这个问题。我是这样解决的:
git config --global core.whitespace cr-at-eol
这基本上告诉 Git 行尾 CR 不是错误。结果,那些烦人的 ^M
字符不再出现在 git diff
、git show
等行的末尾。
它似乎保持其他设置不变;例如,行尾的额外空格仍会在差异中显示为错误(以红色突出显示)。
(其他答案已经提到了这一点,但上面正是如何设置设置。要为一个项目设置设置,请省略--global
。)
编辑:
在经历了许多行结束的痛苦之后,在 .NET 团队工作时,我遇到了最好的运气,使用以下设置:
没有 core.eol 设置
没有 core.whitespace 设置
没有 core.autocrlf 设置
运行 Windows 的 Git 安装程序时,您将获得以下三个选项: Checkout Windows-style, commit Unix-style line endings <-- 选择这一项 Checkout as-is, commit Unix-style line endings Checkout as-is, commit原样
签出 Windows 风格,提交 Unix 风格的行尾 <-- 选择这个
按原样结帐,提交 Unix 风格的行尾
按原样结帐,按原样提交
如果您需要使用空白设置,如果您需要与 TFS 交互,您可能应该仅在每个项目的基础上启用它。只需省略 --global
:
git config core.whitespace cr-at-eol
如果您需要删除一些 core.* 设置,最简单的方法是运行以下命令:
git config --global -e
这将在文本编辑器中打开您的全局 .gitconfig 文件,您可以轻松删除要删除的行。 (或者你可以在它们前面加上'#'来注释掉它们。)
core.autocrlf
自动设置为 true
git config --global core.whitespace cr-at-eol
将关闭其他默认设置。有三个默认值:blank-at-eol、blank-at-eof 和 space-before-tab。因此,要启用 cr-at-eol,同时保留其他功能,您需要使用 git config --global core.whitespace blank-at-eol,blank-at-eof,space-before-tab,cr-at-eol
。
cr-at-eol
删除了 git diff
行末尾的 ^M
好吧,但 GIT 仍然将这些行显示为不同,尽管行尾是唯一的区别。
git help config
。
试试 git diff --ignore-space-at-eol
、git diff --ignore-space-change
或 git diff --ignore-all-space
。
autocrlf
设置。谢谢!
另见:
core.whitespace = cr-at-eol
或等效地,
[core]
whitespace = cr-at-eol
其中 whitespace
前面有一个 tab 字符。
git show
中使用)不再困扰我关于更改行上的 ^M
的问题! :)
git diff
仍显示 ^M 个字符。
git config --global core.whitespace cr-at-eol
(如果您只想在您所在的仓库中使用 --global ,则它是可选的)
[core]
下,所以我可以用 TAB 字符替换 core.
前缀。
git diff
中隐藏 ^M
,而不是首先如何不放入 ^M。这意味着更改 core.autocrlf
的公认答案不是最好的,因为它会在没有用户确认的情况下默默地更改文件。
你为什么在你的 git diff 中得到这些 ^M ?
就我而言,我正在从事一个在 Windows 中开发的项目,我使用的是 Linux。当我更改一些代码时,我在 git diff
中添加的行的末尾看到了 ^M
。我认为 ^M
出现是因为它们的行尾与文件的其余部分不同。因为文件的其余部分是在 Windows 中开发的,所以它使用 CRLF
行结尾,而在 Linux 中它使用 LF
行结尾。
显然,Windows 开发人员在安装 Git 期间没有使用“Checkout Windows-style, commit Unix-style line endings”选项。
那么我们应该怎么做呢?
您可以让 Windows 用户重新安装 git 并使用“Checkout Windows-style, commit Unix-style line endings”选项。这是我更喜欢的,因为我认为 Windows 在其行尾字符中是一个例外,并且 Windows 以这种方式解决了它自己的问题。
如果您选择此选项,则应该修复当前文件(因为它们仍在使用 CRLF
行结尾)。我按照以下步骤做到了这一点:
从存储库中删除所有文件,但不要从您的文件系统中删除。 git rm --cached -r 。添加一个 .gitattributes 文件,强制某些文件使用 LF 作为行尾。将其放入文件中: * text=auto eol=lf 再次添加所有文件。混帐添加。这将显示如下消息:警告:CRLF 将被替换为
现在您的项目仅使用 LF
字符作为行尾,讨厌的 CR
字符将永远不会出现 :)。
另一种选择是强制执行 windows 样式的行尾。您也可以为此使用 .gitattributes
文件。
更多信息:https://help.github.com/articles/dealing-with-line-endings/#platform-all
View
-> Line Endings
并点击 Unix
。
^M
到底是什么意思?它是windows还是linux换行符?还是与文件中的其他换行符相比,它只是一个“不同”的换行符?
git config --global core.autocrlf true
是矫枉过正,反 Windows/反 CR
活动似乎与问题无关。
*.ext text eol=lf
代替 crlf
吗?我认为这是一个错字,没有人注意到!
有没有像“差异时将 ^M 视为换行符”这样的选项?
Git 2.16(2018 年第一季度)将有一个,因为“diff
”系列命令学会了忽略行尾回车的差异。
请参阅 Junio C Hamano (gitster
) 的commit e9282f0(2017 年 10 月 26 日)。
帮助:Johannes Schindelin (dscho
)。
(由 Junio C Hamano -- gitster
-- 在 commit 10f65c2 中合并,2017 年 11 月 27 日)
diff: --ignore-cr-at-eol 一个新选项 --ignore-cr-at-eol 告诉 diff 机制将(完整)行末尾的回车视为不存在。就像其他忽略各种空白差异的“--ignore-*”选项一样,这将有助于查看您所做的实际更改,而不会被您的编辑器程序进行的虚假 CRLF<->LF 转换分心。
git config --global core.autocrlf true
设置为已接受的答案通常是一种很好的做法,但这更直接地回答了 OP 的问题:“是否有类似“区分时将 ^M 视为换行符”的选项?
git version 2.20.1 (Apple Git-117)
上设置我的 core.whitespace 值,但添加 Jason Pyeron 的 core.pager 答案修复了它。 YMMV 很明显。
TL;博士
将 core.pager
更改为 "tr -d '\r' | less -REX"
,而不是源代码
这就是为什么
https://i.stack.imgur.com/ysOdN.png
首先要注意的是 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
\r\n
行结尾,有些有 \n
行结尾(我不知道这是否相关);前者的差异在修改后的行(即 +
行)中显示了 ^M
。 core.autocrlf
设置为 true
。运行 git config core.pager "tr -d '\r' | less -REX"
摆脱了讨厌的 ^M
。谢谢!
git diff -b
是我一直在寻找的,但我非常感谢详尽的解释。
pager = tr -d '\\r' | less -REX
来修改 git“config”文件的 [core]
部分是唯一对我有用的答案。谢谢!
git diff -b
无效,但配置修改有效。
就我而言,它是什么命令:
git config core.whitespace cr-at-eol
来源:https://public-inbox.org/git/8d7e4807-9a79-e357-8265-95f22ab716e0@web.de/T/
我为这个问题苦苦挣扎了很长时间。到目前为止,最简单的解决方案是不用担心 ^M 字符,只需使用可以处理它们的视觉差异工具。
而不是键入:
git diff <commitHash> <filename>
尝试:
git difftool <commitHash> <filename>
正如 VonC 所指出的,这已经包含在 git 2.16+ 中。不幸的是,选项的名称 (--ignore-cr-at-eol
) 与我习惯使用的 GNU diff 使用的名称 (--strip-trailing-cr
) 不同。
当我遇到这个问题时,我的解决方案是调用 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'
但它不使用配置的寻呼机设置,这就是我更喜欢前者的原因。
如果您只想要一条使 git diff
但不显示不同结尾(因此 ^M
)的快速行,请使用原始问题的第一条评论中的那个,它对我有用:
git diff -b
考虑到,从长远来看,您应该正确设置行尾配置,正如所有其他答案所暗示的那样。
如果 git 补丁已经在 Windows 机器中生成并且您正在使用它,您可以在 Linux 中使用 dos2unix 实用程序格式化补丁。
find -name "*.patch"| xargs dos2unix
这将解决 EOL 的 ^M 问题,您将能够在您的 linux 机器中应用 git apply 补丁。
不定期副业成功案例分享
git config core.whitespace cr-at-eol
告诉 get 来处理。warning: LF will be replaced by CRLF
而不是warning: CRLF will be replaced by LF
,而且我在 Linux 中。知道为什么吗?我希望一切都以 LF 结束,而不是 CRLF!git config --global core.autocrlf input
,执行此答案中的步骤(rm,add,commit),您将得到warning: CRLF will be replaced by LF. The file will have its original line endings in your working directory.
。删除文件(因为它们具有原始的错误 CRLF)并从上次“修复 CRLF”提交中再次签出它们。