Search code examples
gitline-endings

git sees entire file as one line due to mac line endings


I am working on Windows platform, with files in Mac ANSI encoding

when I edit a single line of a file, and then do a git diff, this is what I see:

diff --git a/class.php b/class.php
@@ -1 +1 @@
-<?php^Mclass Type {^M^M   private $x;// level^M ..etc
\ No newline at end of file
+<?php^Mclass Type {^M^M   private $x;// level^M ..etc
\ No newline at end of file

In other words, git sees my file as a single line, due to the mac line endings. I have looked at various posts on git hub and got tried a few solutions, but neither worked. I am kind of lost as to what is going on and how to commit my files properly.

Links I have tried:

Still same ^M in lines. git does not seem to handle \r on Windows quite well. Must I convert entire repo line endings to say \r\n? Is there not a solution to leave mac encoding as is?

More info:

My .gitattributes file:

# Set default behaviour, in case users don't have core.autocrlf set.
* text=auto

# Explicitly declare text files we want to always be normalized and converted
# to native line endings on checkout.
*.php text
*.inc text
*.js text
*.txt text

# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf

# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
*.gif binary

I ran this command: git config --global core.autocrlf true


Solution

  • TL;DR version

    #rewrite ALL your branches, ALL trees, ALL commits to use proper line endings
    git filter-branch --tree-filter '~/fix-eol.sh' -d /dev/shm/repo-temp --tag-name-filter cat  --prune-empty -- --all
    
    #git may complain after this procedure and have unclean directory.  Just do:
    git reset --hard
    
    #go over your repo and delete your tags and old tree references, 
    #old branch pointers on both remote and local
    git tag -d v1.1.0
    git push . :refs/original/refs/tags/v1.1.0
    etc...
    
    #re-compress your objects..
    git gc --aggressive
    
    #some more clean up
    git prune
    
    #CAUTION:  this will rewrite your origin repo, 
    #you (and everybody else) using it will have to run git clone 
    #to re-download the entire repo.  This was a destructive operation afterall
    #(normalizing all line endings in your entire repo)
    git push --force
    

    cat ~/fix-eol.sh

    #!/bin/bash
    # ~/fix-eol.sh
    # convert all js,css,html, and txt files from DOS to UNIX line endings
    find . -type f -regex ".*\.\(js\|css\|inc\|html\|txt\|php\)" | xargs perl -pi -e 's/\r\n|\n|\r/\n/g'
    

    Long version:

    I said the heck with it and now trying the 2nd solution described here:

    http://blog.gyoshev.net/2013/08/normalizing-line-endings-in-git-repositories/

    normalizing all my text and code containing files to contain \n unix-style line endings, using dos2unix command (dos2unix did not work for mac, ha haha, of course! It's not mac2unix)

    so I used the converter here: Converting newline formatting from Mac to Windows

    It rewrites entire repository, now with proper line endings, and I think that after push --force and people redownloading the repository, all will be okay.