0

I've faced some unclear behavior of how GIT manages line endings. There are a bunch of *.sh files in my repository. Line endings are inconsistent: some have CRLF line endings while others have LF line endings. When I refreshed repository by rm .git\index and git reset all *.sh files marked as changed. I've inverted line endings manually for some of these *.sh files and refreshed repository, but these files still considered as changed by git status.

I've tried this with different combinations of autocrlfand .gitattribute settings:

autocrlf=true - *.sh text eol=lf

autocrlf=true - *.sh eol=lf

autocrlf=false - *.sh text eol=lf

autocrlf=false - *.sh eol=lf

Why are none of these forced LF line endings for *.sh files and all files remains changed despite of line endings type?

Dylan Wheeler
  • 6,928
  • 14
  • 56
  • 80
alaptiko
  • 499
  • 3
  • 14
  • This gets complicated. It depends on whether the files in the `HEAD` commit actually have the desired line endings, whether the files in the work-tree have the desired line endings, and what exactly is in the index, including file system time stamps. Once the `HEAD` commit and work-tree agree with each other's conversion process, most of the weirdness (including slowness of `git status`) will go away, but there is still the "racily clean" issue with filters and checkouts that take less than one second. – torek May 31 '17 at 15:25
  • I've just deleted files and reverted ```DELETED``` action by ```git checkout -- .``` so line endings seems are different in ```HEAD``` too. – alaptiko Jun 01 '17 at 07:38
  • It's useful to know that the way the line-ending (or indeed any) conversions work is that they are applied when the file moves from the index to the work-tree, or vice versa, i.e., at the `git checkout-index` or `git add` step. Git then writes the *time stamp* of the work-tree file into the index as well in order to decide whether it must repeat the conversion work to determine whether the work-tree data match the index hash for that file. Meanwhile the index vs HEAD (same-or-different) test is easy as that's just a hash ID comparison. – torek Jun 01 '17 at 14:37
  • Meanwhile, the `core.autocrlf` setting itself is used *only* if there's no explicit `text` setting: If `text` is set (`text`) or unset (`-text`) or set-to-auto (`text=auto`), `core.autocrlf` is irrelevant. Otherwise `core.autocrlf` determines the next decision. And, `eol=` effectively acts like you set `text`, which thus overrides `core.autocrlf`. `eol=lf` means "*do nothing* on extract-from-index-to-work-tree, replace crlf with lf-only on copy-from-work-tree-to-index." If the *committed* version has CRLFs in it, note that this leaves the CRLFs in the work-tree! – torek Jun 01 '17 at 14:45

0 Answers0