mjcconsulting
mjcconsulting

Reputation: 85

How to override line endings within subdirectories via .gitattributes for no extension + specified extension?

I need to clone a repo containing bash and PowerShell scripts to both MacOS and Windows systems, edit via Atom on both, run bash scripts native on MacOS or via Ubuntu WSL shell on Windows, run PowerShell scripts in PowerShell window on Windows Only.

On MacOS, all files should be checked out with Native (LF) endings.

On Windows, all files should be checked out with Native (CRLF) endings, with exceptions:

Basically, we can use * text=auto, then override for specific file extensions, with one special case - bash scripts inside a bin directory at any level will not generally have any extension, including *.sh.

The reason this is needed is because with normal behavior, bash scripts checked out with CRLF line ending in the Windows filesystem, can't run when accessed via the /mnt/c path within WSL. We need to edit AND run them before we commit.

I have found and tried solutions shown in problems found here, which seem to show I can override default auto text handling with directory-specific overrides. This works, but then additional overrides that are more specific do not work.

/.gitattributes:

# Autodetect text files
* text=auto

# Explicitly identify binary files
*.xls binary
*.xlsx binary
*.doc binary
*.docx binary
*.vsd binary
*.vsdx binary
*.pdf binary
*.png binary
*.jpg binary
*.gif binary

# Explicitly identify script files
*.sh text eol=lf
*.ps1 text
*.bat text
*.cmd text
bin/* text eol=lf
bin/*.ps1 text=auto
bin/*.bat text=auto
bin/*.cmd text=auto

# Explicitly identify text files
*.txt text
*.md text
*.json text
*.yaml text

Expected results on Linux = all files use native, LF line endings. This appears to work.

Expected results on Windows:

/test - expect CRLF - correct
/test.sh - expect LF - correct
/test.ps1 - expect CRLF - correct
/bin/test - expect LF - correct
/bin/test.sh - expect LF - correct
/bin/test.ps1 - expect CRLF - INCORRECT, uses LF
/bin/test.bat - expect CRLF - INCORRECT, uses LF

I haven't tested this explicitly, but also expect this:

/templates/test - expect CRLF
/templates/test.sh - expect LF
/templates/test.yaml - expect CRLF
/templates/test.ps1 - expect CRLF

/section1/test - expect CRLF
/section1/test.sh - expect LF
/section1/test.ps1 - expect CRLF
/section1/bin/test - expect LF
/section1/bin/test.sh - expect LF
/section1/bin/test.ps1 - expect CRLF

Upvotes: 1

Views: 967

Answers (1)

jthill
jthill

Reputation: 60605

Does "on Windows" mean "with core.autocrlf set"? Afaik Git doesn't hardwire defaults to the OS, but Windows installs' templates usually have core.autocrlf set.

At any rate, I think you might have missed

When more than one pattern matches the path, a later line overrides an earlier line. This overriding is done per attribute.

in the attributes docs; you've got an explicit

bin/* text eol=lf

setting eol for everything in bin, and your bin/*.ps1

bin/*.ps1 text=auto

doesn't override it, so bin/*.ps1 inherits the explicit eol=lf attribute. You can verify that with git check-attr eol bin/any.ps1 or git check-attr -a bin/any.ps1.

So if my coffee's still functioning correctly, the fix should be to add -eol to your bin/*.ps1 attribute pattern to override your earlier bin/* eol=lf force.

Upvotes: 3

Related Questions