Skip to content

LF line endings everywhere #12

Description

@rent-a-developer

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

  1. Replace the five shell/batch scripts with three PowerShell scripts, and update every reference.
  2. .gitattributes: * text=auto eol=lf plus the binary list. No per-type text pins.
  3. .editorconfig: end_of_line from crlf to lf; drop the now-redundant [*.sh] override.
  4. CI lint: call tidy-code.ps1 -Check, move to ubuntu-latest, and add a renormalization guard and
    a .git-blame-ignore-revs check.
  5. Renormalize, add .git-blame-ignore-revs, and document the policy in CONTRIBUTING.md.

Acceptance criteria

  • .gitattributes contains no per-type text pins.
  • .editorconfig sets end_of_line = lf.
  • git ls-files --eol shows no i/crlf or i/mixed entries.
  • CI fails when a committed file does not match the attributes.
  • No .cmd, .bat or .sh files remain, and no reference to the old script names.
  • pwsh -File scripts/tidy-code.ps1 -Check passes on Windows as well as Linux.
  • Running pwsh -File scripts/tidy-code.ps1 leaves no files reported as modified.
  • .git-blame-ignore-revs exists and CI verifies its revisions.
  • CONTRIBUTING.md explains the policy.

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions