Problem
.gitattributes pins working-tree line endings per file type: eol=crlf for .cs, .csproj, .xaml,
.axaml, .resx and others, LF for .json, .yml, .md, .sh. .editorconfig sets
end_of_line = crlf.
This costs us:
Directory.Packages.props is stored with CRLF while its attribute asks for LF in the index, so
git diff reports a whole-file change on a clean checkout and never stops. git checkout -- cannot
repair it; only git add --renormalize can.
- Every new file type needs a decision. The types nobody listed —
Settings.XamlStyler,
*.DotSettings, PublicAPI.*.txt, nuget.config, .svg — fall back to each contributor's
core.autocrlf.
- The formatting check is stuck on a Windows runner. XamlStyler writes the host OS newline and has no
setting for it, so its passive check only passes where the host newline matches the checkout. Linux
and macOS contributors can never run a passing XAML check locally.
- Nothing verifies that stored files match the attributes, so drift stays invisible.
Proposal
One rule: * text=auto eol=lf, plus end_of_line = lf in .editorconfig and a CI step that proves the
repository stays normalized.
XamlStyler cannot write LF, so the format script must correct it afterwards. That is folded into a new
scripts/tidy-code.ps1, which replaces formatCode.cmd and formatCode.sh with one cross-platform
script. Its -Check mode formats the tree and asks whether that changed anything, which gives the same
answer on every OS — so the formatting gate can finally be run locally on Windows, Linux and macOS, and
CI calls the same entry point a developer does.
While replacing that pair, replace the other shell/batch scripts with PowerShell equivalents too:
clean.cmd/clean.sh become scripts/clean-build-artifacts.ps1, and extract-release-notes.sh
becomes scripts/extract-release-notes.ps1. The repository then has no .cmd, .bat or .sh files at
all, so the LF rule needs no exception.
Scope
- Replace the five shell/batch scripts with three PowerShell scripts, and update every reference.
.gitattributes: * text=auto eol=lf plus the binary list. No per-type text pins.
.editorconfig: end_of_line from crlf to lf; drop the now-redundant [*.sh] override.
- CI
lint: call tidy-code.ps1 -Check, move to ubuntu-latest, and add a renormalization guard and
a .git-blame-ignore-revs check.
- Renormalize, add
.git-blame-ignore-revs, and document the policy in CONTRIBUTING.md.
Acceptance criteria
Notes
Merge with a merge commit. Squash and rebase rewrite the SHA in .git-blame-ignore-revs, and git
silently ignores an entry it cannot resolve.
Suggested branch: chore/lf-line-endings.
Problem
.gitattributespins working-tree line endings per file type:eol=crlffor.cs,.csproj,.xaml,.axaml,.resxand others, LF for.json,.yml,.md,.sh..editorconfigsetsend_of_line = crlf.This costs us:
Directory.Packages.propsis stored with CRLF while its attribute asks for LF in the index, sogit diffreports a whole-file change on a clean checkout and never stops.git checkout --cannotrepair it; only
git add --renormalizecan.Settings.XamlStyler,*.DotSettings,PublicAPI.*.txt,nuget.config,.svg— fall back to each contributor'score.autocrlf.setting for it, so its passive check only passes where the host newline matches the checkout. Linux
and macOS contributors can never run a passing XAML check locally.
Proposal
One rule:
* text=auto eol=lf, plusend_of_line = lfin.editorconfigand a CI step that proves therepository stays normalized.
XamlStyler cannot write LF, so the format script must correct it afterwards. That is folded into a new
scripts/tidy-code.ps1, which replacesformatCode.cmdandformatCode.shwith one cross-platformscript. Its
-Checkmode formats the tree and asks whether that changed anything, which gives the sameanswer on every OS — so the formatting gate can finally be run locally on Windows, Linux and macOS, and
CI calls the same entry point a developer does.
While replacing that pair, replace the other shell/batch scripts with PowerShell equivalents too:
clean.cmd/clean.shbecomescripts/clean-build-artifacts.ps1, andextract-release-notes.shbecomes
scripts/extract-release-notes.ps1. The repository then has no.cmd,.bator.shfiles atall, so the LF rule needs no exception.
Scope
.gitattributes:* text=auto eol=lfplus the binary list. No per-type text pins..editorconfig:end_of_linefromcrlftolf; drop the now-redundant[*.sh]override.lint: calltidy-code.ps1 -Check, move toubuntu-latest, and add a renormalization guard anda
.git-blame-ignore-revscheck..git-blame-ignore-revs, and document the policy inCONTRIBUTING.md.Acceptance criteria
.gitattributescontains no per-type text pins..editorconfigsetsend_of_line = lf.git ls-files --eolshows noi/crlfori/mixedentries..cmd,.bator.shfiles remain, and no reference to the old script names.pwsh -File scripts/tidy-code.ps1 -Checkpasses on Windows as well as Linux.pwsh -File scripts/tidy-code.ps1leaves no files reported as modified..git-blame-ignore-revsexists and CI verifies its revisions.CONTRIBUTING.mdexplains the policy.Notes
Merge with a merge commit. Squash and rebase rewrite the SHA in
.git-blame-ignore-revs, and gitsilently ignores an entry it cannot resolve.
Suggested branch:
chore/lf-line-endings.