views:

1949

answers:

2

I have been bitten by the windows/linux line-ending issue with git. It seems, via github, msysgit, and other sources, that the best solution is to have your local repos set to use linux-style line endings, but set core.autocrlf to true. Unfortunately, I didn't do this early enough, so now every time I pull changes the line endings are borked.

I thought I had found an answer here but I can't get it to work for me. My linux command line knowledge is limited at best, so i am not even sure what the "xargs fromdos" line does in his script. I keep getting messages about no such file or directory existing, and when I manage to point it to an existing directory, it tells me I don't have permissions.

I've tried this with msysgit on windows and via the Mac OS X terminal. Any help would be GREATLY appreciated.

+1  A: 

The "| xargs fromdos" reads from standard input (the files find finds) and uses it as arguments for the command fromdos, which converts the line endings. (Is fromdos standard in those enviroments? I'm used to dos2unix). Note that you can avoid using xargs (especially useful if you have enough files that the argument list is too long for xargs):

find <path, tests...> -exec fromdos '{}' \;

or

find <path, tests...> | while read file; do fromdos $file; done

I'm not totally sure about your error messages. I successfully tested this method. What program is producing each? What files/directories do you not have permissions for? However, here's a stab at guessing what your it might be:

One easy way to get a 'file not found' error for the script is by using a relative path - use an absolute one. Similarly you could get a permissions error if you haven't made your script executable (chmod +x).

Add comments and I'll try and help you work it out!

Jefromi
I saw another example with dos2unix and I thought this was somehow copying files into a folder named that, but now I get it. Wow, seems obvious now. Thanks for your help!
Brian Donahue
+23  A: 

The easiest way to fix this is to make one commit that fixes all the line endings. Assuming that you don't have any modified files, then you can do this as follows.

# From the root of your repository remove everything from the index
git rm --cached -r .

# Change the autocrlf setting of the repository (you may want 
#  to use true on windows):
git config core.autocrlf input

# 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 "Fixed crlf issue"

# If you're doing this on a Unix/Mac OSX clone then optionally remove
# the working tree and re-check everything out with the correct line endings.
git ls-files -z | xargs -0 rm
git checkout .
Charles Bailey
I got the same recommendation from Github. Not in love with it, but rewriting history also makes me nervous. I may just go with this solution for now.
Brian Donahue
I'm actually going to mark your answer the fix because it was the one I went with. It was the only one that actually did seem to get all files at once. Others seemed to only get a few files at a time and each pull and checkout exposed more files that needed to be changed. Thanks!
Brian Donahue
P.S. I recommended your fix to the guys at github.com and they updated their help guide to use your solution (previously it had just recommended a fresh clone and a hard reset, which did not seem to get all files.) http://help.github.com/dealing-with-lineendings/
Brian Donahue
Thanks... this is a great fix. Found it oh GitHub.
PHLAK
You may also want to check out config.safecrlf to ensure that you aren't changing crlfs in non-text files (such as binary). Check it out in the docs http://www.kernel.org/pub/software/scm/git/docs/git-config.html.
vrish88
@vrish88: If you're in this situation, though, you're likely to be suffering from mixed lined endings and core.safecrlf may actually prevent you from doing what you need to do. It's probably easier to not use safecrlf. git doesn't often get binary file detection wrong and if it does you can manually mark it as binary with a .gitattribute and recover the correct version from the previous commit.
Charles Bailey