gitnewlinediffgit-diffcarriage-return

Make 'git diff' ignore ^M


In a project where some of the files contain ^M as newline separators, diffing these files is apparently impossible, since git diff sees the entire file as just a single line.

How does one git diff when comparing the current and previous versions of a source code file?

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:

I have written a Ruby 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

Solution

  • 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:

    $ 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 …

    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.