2

I have files in a git repo with LF endings. Somehow some of the files in my working tree got converted to CRLF. Is there a way to convert the line endings in my working tree back to LF?

Note that I have a few files in the directory .gitignored so I don't want to simply delete everything and check it out again (though if there's a way to only delete tracked files and check them out again that would work I guess).

Timmmm
  • 88,195
  • 71
  • 364
  • 509

2 Answers2

6

The main problem with using git checkout HEAD -- . or git checkout HEAD -- path is that Git tries to optimize away the checkout, if Git thinks there's no need to do the checkout.1 As you noted in your own answer, git reset has the same optimization.

There are several ways to defeat the optimization. The one you chose—using git ls-files -z | xargs -0 rm -f—works fine. Another is to touch each file that you want Git to overwrite: this invalidates the cache data in Git's index. Since touch doesn't actually modify the file, this can be simpler: touch * is usually fairly painless. It doesn't handle subdirectories, though. You could run git ls-files -z | xargs -0 touch, which is almost the same as in your answer.


1Obviously, if CRLF-handling for index-to-work-tree copying has changed since the previous index-to-work-tree copy step, this optimization is incorrect: Git does need to do the checkout. But Git's cache doesn't realize that. Possibly there should be a plumbing command, git whack-cache or git frotz-index or something, that just invalidates each cache entry, so as to force a real checkout.

torek
  • 448,244
  • 59
  • 642
  • 775
2

I couldn't find a better solution than deleting all tracked files and checking them out again. In particular no variant of git checkout -f -- . or git reset --hard has any effect on the file.

As recommended here:

git ls-files -z | xargs -0 rm -f
git checkout .

Not an elegant solution but it did work.

Timmmm
  • 88,195
  • 71
  • 364
  • 509
  • I wonder if you've seen [git checkout and reset a mess](https://redfin.engineering/two-commits-that-wrecked-the-user-experience-of-git-f0075b77eab1). Adding the narrower focussed [switch and restore](https://www.infoq.com/news/2019/08/git-2-23-switch-restore/) as correction. IOW try to rewrite checkout as restore. You'll need 2.23 or later – Rusi Oct 04 '20 at 16:04
  • Neither reset nor checkout work - they are too "smart" and avoid modifying files if necessary. Arguably a bug in this case but I imagine fixing it would be difficult. – Timmmm Oct 05 '20 at 21:44