zscripts-token-savers/.gitattributes
KellyMichels 33b3fb6f90 fix: pin the .txt twins to LF so regenerating them stops reporting a change
Three things disagreed about line endings, and the generator lost:

  stored in git      LF
  checked out        CRLF   (core.autocrlf - nothing pinned *.txt)
  written by the     LF     (plaintext_twins.py, newline="\n")
  generator

So every run wrote LF over a CRLF checkout, git status reported each twin as
modified, and git add normalized it straight back to LF for an empty diff.

A generator that always reports work hides the one time it did some. It also
puts noise in front of the reviewer on every publish - exactly where a real
change should be easy to see - and trains the reader to discard the twins
without looking, which is how genuine drift gets thrown away.

Pinning *.txt to eol=lf makes checkout agree with both the generator and the
stored form. Verified: regenerate, and only .gitattributes is modified.

CHECKSUMS.txt keeps its own explicit line even though *.txt now covers it.
Its reason is different in kind - sha256sum -c treats a trailing CR as part
of the filename and reports every entry as missing, which is a broken
verification rather than a cosmetic diff - and that should not silently
depend on a glob above it staying where it is.

Closes #88

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 20:15:11 -05:00

24 lines
1.1 KiB
Plaintext

# PowerShell/cmd are happiest with CRLF on Windows. The pin matters beyond
# convenience: it makes these files byte-identical on every platform, which is
# what lets CHECKSUMS.txt hold one hash per file rather than one per OS.
*.ps1 text eol=crlf
*.cmd text eol=crlf
# Every .txt here is either a generated twin or a manifest, and all of them
# want LF. plaintext_twins.py writes LF and git stores LF, but without this
# pin checkout applied core.autocrlf and handed the working tree CRLF - so
# every regeneration rewrote the file to LF, `git status` reported a change,
# and `git add` normalized it straight back to nothing (#88). Pinning the
# checkout makes all three agree.
*.txt text eol=lf
# Kept explicit even though *.txt already covers it: the checksum manifest
# must stay LF because `sha256sum -c` treats a trailing CR as part of the
# filename and reports every entry as missing. That is a broken verification,
# not a cosmetic diff, and it should not depend on a glob above it.
CHECKSUMS.txt text eol=lf
releases/*.sha256 text eol=lf
# Release zips are binary and immutable.
releases/*.zip binary