pub fn normalise_to_lf(content: &[u8]) -> Vec<u8> ⓘExpand description
Replaces every CRLF with LF.
A lone CR is left alone: it is not a line ending git would have produced,
and rewriting it would corrupt content that merely happens to contain the
byte.
Not idempotent in general — \r\r\n collapses to \r\n and would
collapse again to \n on a second pass, exactly as git’s own conversion
does. Under text=auto, which is the default and so the mode almost every
path is in, that never happens: content carrying a lone CR is classified
binary by looks_binary and is never normalised at all.
An explicit text bypasses that classifier, so a path declared
secrets/*.sh text whose content holds \r\r\n does not round-trip: clean
stores \r\n, smudge writes it back, and the next clean collapses it again,
so git status reports the file as modified until it is added again — which
stores the collapsed bytes. Git does the same thing with an explicit text
attribute, and measured on 2.55 it does not warn about it even with
core.safecrlf=warn.
That is not the only shape, and not the worst one. Mixed CRLF and lone LF
is normalised under plain text=auto too, so the default mode loses the
distinction as well — and there git status stays clean while the working
tree changes, because the new bytes normalise to the same plaintext.
[survives_the_round_trip] answers for both, and the filter warns; Open
Decision 8 in context/foundation/zalozenia.md closed on 2026-08-06.
Recorded here rather than claimed away, because an earlier version of this
comment asserted the invariant held everywhere.