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.
How does one diff with the previous version?
Is there an option like "treat ^M as newline when diffing" ?
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 script that checks out the latest 10 revisions and converts CR to 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
If you are using Eclipse, you can make the
^M
disappear fromgit diff
by settingFile > Convert Line Delimiter To > Unix (LF, \n, 0A, ¶)
TL;DR
Change the
core.pager
to"tr -d '\r' | less -REX"
, not the source codeThis 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 isless -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)setup:
A quick test to create a unix file and change the line endings will show no changes with
git diff -b
:We note that forcing a pipe to less does not show the ^M, but enabling color and
less -R
does:The fix is shown by using a pipe to strip the \r (^M) from the output:
An unwise alternative is to use
less -r
, because it will pass through all control codes, not just the color codes.If you want to just edit your git config file directly, this is the entry to update/add:
Developing on Windows, I ran into this problem when using
git tfs
. I solved it this way: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 ingit diff
,git show
, etc.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
.)EDIT:
After many line-ending travails, I've had the best luck, when working on a .NET team, with these settings:
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
:If you need to remove some core.* settings, the easiest way is to run this command:
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.)
GitHub suggests that you should make sure to only use \n as a newline character in git-handled repos. There's an option to auto-convert:
Of course, this is said to convert crlf to lf, while you want to convert cr to lf. I hope this still works …
And then convert your files:
core.autocrlf is described on the man page.
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.
Instead of typing:
try:
Why do you get these
^M
in yourgit 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 ingit 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 usedCR
line endings, and in OS X it usesLF
line endings.Apparently, the Windows developer didn't use the option "Checkout Windows-style, commit Unix-style line endings" during the installation of Git.
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 it's line ending characters and Windows fixes it's own issue this way.
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:Remove all files from the repository, but not from your filesystem.
Add a
.gitattributes
file that enforces certain files to use aLF
as line endings. Put this in the file:Replace
.ext
with the file extensions you want to match.Add all the files again.
This will show messages like this:
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:
You can do something like this to remove the files:
And then this to get them back with the correct line endings:
Of course replacing
.ext
with the extension you want.Now your project only uses
LF
characters for the line endings, and the nastyCR
characters won't ever come back :).The other option is to enforce windows style line endings. You can also use the
.gitattributes
file for this.More info: https://help.github.com/articles/dealing-with-line-endings/#platform-all