git-diff忽略^ M.

neo*_*eye 423 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>
Run Code Online (Sandbox Code Playgroud)

更新:

现在我编写了一个脚本,检查最新的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
Run Code Online (Sandbox Code Playgroud)

nes*_*983 352

GitHub建议您确保只使用\n作为git-handling repos中的换行符.有一个自动转换选项:

$ git config --global core.autocrlf true
Run Code Online (Sandbox Code Playgroud)

当然,据说将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"
Run Code Online (Sandbox Code Playgroud)

core.autocrlf 在手册页中描述.

  • 你没有在这里使用CRLF文件,至少在你发布的例子中没有.这是一个旧式的mac文件(只使用\ r进行EOL).这就是差异显示在一条线上的原因.使用dos EOL的文件会显示每行明显的尾随^ M,您可以通过`git config core.whitespace cr-at-eol`来处理. (61认同)
  • 我正在尝试这个,但我一直得到`警告:LF将被CRLF替换而不是`警告:CRLF将被LF替换,我在Linux中.知道为什么吗?我希望所有人都以LF结束,而不是CRLF! (11认同)
  • @trusktr,它发生在我身上.在linux中,使用偶然的CRLF,使用`git config --global core.autocrlf input`,执行这个答案中的步骤(rm,add,commit),你会得到`警告:CRLF将被LF取代.该文件将在您的工作目录中具有其原始行结尾.删除文件(因为它们具有原始的,错误的CRLF)并从最后一次"修复CRLF"提交中再次检出它们. (5认同)
  • 问题是我已经在存储库中有一些文件具有 CRLF 结尾而其他文件没有。我怀疑即使我使用的是 Mac 版本,Adobe Flash 也会添加 CRLF。我需要与这些文件的旧版本进行比较。从现在开始转换行尾并不能解决旧版本的问题:-/ (2认同)

Rya*_*ndy 346

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

git config --global core.whitespace cr-at-eol
Run Code Online (Sandbox Code Playgroud)

这基本上告诉Git,行尾CR不是错误.其结果是,那些烦人的^M字符不再出现在线路末端git diff,git show等等.

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

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

编辑:

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

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

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

git config core.whitespace cr-at-eol
Run Code Online (Sandbox Code Playgroud)

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

git config --global -e
Run Code Online (Sandbox Code Playgroud)

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

  • 对于那些现在发现这一点的人来说,值得注意的是**Checkout Windows风格,提交Unix风格的行结尾**自动设置`core.autocrlf`为`true` (29认同)
  • 请注意,`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` . (12认同)
  • 我认为 git 需要更复杂一些,为行尾设置更多冲突的设置。我认为 git 应该*更多*关注我的空格。例如,当在 Windows(但不是 Linux)机器上遇到 Mac 行结尾时,抛出一个无关的致命错误并使存储库处于损坏状态。我的意思是为什么我会使用一个会介意它的业务并让我使用我想要的任何行结尾的 VCS?我看到他们正在尝试,但他们应该再加入六个行结束行为,以解决一个不存在的问题。他们快到了!保持。 (5认同)
  • 对于我的项目(它是在 Windows 上结帐,而我正在 Linux 上查看它),`cr-at-eol` 在`git diff` 行尾去掉了 `^M`,好吧,但 GIT 仍然存在将这些行显示为不同,尽管行尾是唯一的区别。 (2认同)
  • @Zitrax 的评论是错误的;core.whitespace 的默认值为“”。例如,如果您想启用 cr-at-eol 并禁用 Blank-at-eol,则需要将 core.whitespace 设置为“cr-at-eol -blank-at-eol”。另请参阅“git 帮助配置”。 (2认同)

Jak*_*ski 114

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

  • 这些都不会影响标识换行符的字符. (18认同)
  • 这些标志对我没有影响......仍然显示^ M作为差异 (9认同)
  • 这解决了我的问题,而无需更改我的`autocrlf`设置.谢谢! (8认同)
  • 我也试过"-w"但没有运气,仍然把它视为单行.下一个项目我必须记住,从来没有得到任何CR到​​源代码. (4认同)
  • 只记得git config --global core.autocrlf是真的,或者让git人犯错误,直到他们将其设为默认值:) (3认同)
  • @Magnus:这些标志是关于Git认为有区别的.它们的使用使得如果行尾约定发生变化,Git不会将整个文件显示为已更改.这不是输出过滤器 - 如果有变化,它将显示为^ M. 您可以尝试配置`less`,或更改Git寻呼机.HTH (2认同)
  • @Magnus:你看到`git diff -w --stat`和`git diff --stat`之间的区别吗?如果差异仅在^ M(即CR LF与LF),则前者不应显示任何变化. (2认同)

Vla*_*eev 101

另见:

core.whitespace = cr-at-eol
Run Code Online (Sandbox Code Playgroud)

或等效地,

[core]
    whitespace = cr-at-eol
Run Code Online (Sandbox Code Playgroud)

其中whitespace制表符为前缀.

  • 有两种方法可以做到这一点:一,在.git/config或〜/ .gitconfig中将上面的行逐字添加到你的.gitconfig中; 二,`git config --global core.whitespace cr-at-eol`(其中--global是可选的,如果你只想在它上面的repo上) (6认同)
  • 这对我也有帮助.但我没有使用相同的标记. (4认同)
  • 是的,这使得git diff工具(也用于`git show`)不再让我知道更改线上的`^ M`s!:) (3认同)
  • 无论出于何种原因,这对我不起作用.尝试使用=和no =符号.`git diff`仍显示^ M个字符. (2认同)

git*_*rik 40

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

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

显然,Windows开发人员在安装Git期间没有使用" Checkout Windows风格,提交Unix风格的行结尾 " 选项.

那我们该怎么做呢?

您可以让Windows用户重新安装git并使用" Checkout Windows风格,提交Unix风格的行结尾 "选项.这是我更喜欢的,因为我认为Windows是一个例外,它的行结束字符和Windows通过这种方式修复了它自己的问题.

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

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

    git rm --cached -r .
    
    Run Code Online (Sandbox Code Playgroud)
  2. 添加.gitattributes强制某些文件的文件以使用LFas行结尾.把它放在文件中:

    *.ext text eol=crlf
    
    Run Code Online (Sandbox Code Playgroud)

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

  3. 再次添加所有文件.

    git add .
    
    Run Code Online (Sandbox Code Playgroud)

    这将显示如下消息:

    warning: CRLF will be replaced by LF in <filename>.
    The file will have its original line endings in your working directory.
    
    Run Code Online (Sandbox Code Playgroud)
  4. 您可以删除该.gitattributes文件,除非您有顽固的Windows用户不想使用" Checkout Windows风格,提交Unix风格的行结尾 "选项.

  5. 承诺并全力以赴.

  6. 删除并签出所有使用它们的系统上的适用文件.在Windows系统上,确保它们现在使用" Checkout Windows风格,提交Unix风格的行结尾 "选项.您还应该在执行这些任务的系统上执行此操作,因为当您添加文件时git说:

    The file will have its original line endings in your working directory.
    
    Run Code Online (Sandbox Code Playgroud)

    您可以执行以下操作来删除文件:

    git ls | grep ".ext$" | xargs rm -f
    
    Run Code Online (Sandbox Code Playgroud)

    然后用正确的行结尾让它们回来:

    git ls | grep ".ext$" | xargs git checkout
    
    Run Code Online (Sandbox Code Playgroud)

    当然要替换.ext你想要的扩展名.

现在你的项目只使用LF行结尾的CR字符,而讨厌的字符将永远不会回来:).

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

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

  • 要修复特定文件中的所有行结尾,如果使用Sublime Text,您可以转到`View` - >`Line Endings`并单击`Unix`. (4认同)
  • -1 因为重新安装 git 来完成 `git config --global core.autocrlf true` 是矫枉过正,而反 Windows/反 `CR` 运动似乎与这个问题无关。 (4认同)

Von*_*onC 33

有没有像"在分辨时将^ M视为换行符"的选项?

将有一个Git 2.16(2018年第一季度),作为" diff"系列命令学会忽略行尾的回车差异.

请参阅Junio C Hamano()提交的e9282f0(2017年10月26日). 帮助:Johannes Schindelin().(由Junio C Hamano合并- -提交10f65c2,2017年11月27日)gitster
dscho
gitster

DIFF: --ignore-cr-at-eol

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

就像--ignore-*忽略各种空白差异的其他" 选项" 一样,这将有助于回顾您所做的真正更改,而不会被CRLF<->LF编辑器程序的虚假转换分散注意力.

  • 通常,按照公认的答案将git config --global core.autocrlf true设置为最佳做法,这将更直接地回答OP的问题:“是否有类似“将^ M作为差异时的换行符”的选项? (3认同)
  • 从 Git 2.20 开始,这并没有隐藏 ^M (2认同)

Jas*_*ron 20

TL; DR

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

这就是为什么

显示的那些讨厌的^ M是着色和寻呼机的人工制品. 在此输入图像描述 它是由less -R默认的git pager选项引起的.(git的默认寻呼机是less -REX)

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

建立:

git clone https://github.com/CipherShed/CipherShed
cd CipherShed
Run Code Online (Sandbox Code Playgroud)

创建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
Run Code Online (Sandbox Code Playgroud)

我们注意到强制管道减少不显示^ 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
Run Code Online (Sandbox Code Playgroud)

通过使用管道从输出中剥离\ 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
Run Code Online (Sandbox Code Playgroud)

一个不明智的选择是使用less -r,因为它将通过所有控制代码,而不仅仅是颜色代码.

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

[core]
        pager = tr -d '\\r' | less -REX
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你 如果您必须在仓库中使用不同的行尾,这是唯一的答案-例如,您按原样使用checkout,按原样提交。 (3认同)

小智 16

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

git config  core.whitespace cr-at-eol
Run Code Online (Sandbox Code Playgroud)

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

  • git config core.whitespace cr-at-eol 这应该是公认的答案。这些其他修复均不适用于最新的 MacOS。其他修复似乎可以在较旧的 Mac 操作系统上运行。 (2认同)
  • 我选择仅将其应用于我的本地环境:`git config --local core.whitespace cr-at-eol` 我使用的是 macOS Ventura 13.4.1。这个建议对我来说很有效。其他评论中给出的建议没有效果。 (2认同)

小智 12

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

而不是输入:

git diff <commitHash> <filename>
Run Code Online (Sandbox Code Playgroud)

尝试:

git difftool <commitHash> <filename>
Run Code Online (Sandbox Code Playgroud)