fix(diff): compare files byte-accurately instead of by normalized lines - #3471
Open
Hydr0gen19 wants to merge 1 commit into
Open
fix(diff): compare files byte-accurately instead of by normalized lines#3471Hydr0gen19 wants to merge 1 commit into
Hydr0gen19 wants to merge 1 commit into
Conversation
`rtk diff a b` split both files with `str::lines()`, which drops the line terminator. CRLF vs LF and a missing final newline therefore produced an empty change list, so byte-different files were reported as "[ok] Files are identical" and exited 0. Since the `diff` rewrite rule routes plain `diff a b` through rtk, this made rtk unusable as an equality oracle in scripts and agent workflows. Byte equality is now the only path to exit 0. When the contents differ but every line matches, the terminators are the only possible cause and the output says so instead of claiming the files are identical. `--ignore-whitespace` keeps the lenient comparison available: it trims trailing whitespace and ignores line endings and the final newline.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
rtk diff a bcompared files withstr::lines(), which drops the line terminator. CRLF vs LF and a missing final newline produced an empty change list, so byte-different files were reported as[ok] Files are identicaland exited0. Comparison is now byte-accurate: only strictly equal contents exit0.--ignore-whitespaceto keep the lenient comparison available on request (trims trailing whitespace, ignores line endings and the final newline).Fixes #3469Why this matters beyond
rtk diffsrc/discover/rules.rsrewrites plaindiff <args>tortk diff, so an agentrunning
diff a bgot the false-equal answer and the0exit code without everasking for rtk. That is exactly the case the issue describes as breaking
diff-based equality checks.
Behaviour
[ok] Files are identical, exit 0[ok] Files are identical, exit 0identical line content; files differ in line endings or the final newline, exit 1[ok] Files are identical, exit 0--ignore-whitespace, whitespace-only difference[ok] Files are identical (ignoring whitespace), exit 0Trailing-space differences were already reported as changes before this PR; they
still are, and
--ignore-whitespacenow suppresses them.Note: for very small files
guard::never_worsestill prefers the raw contentover the condensed message, as it does for every other
rtk diffoutput. Theexit code — the part scripts rely on — is correct in every case.
On the added flag
--ignore-whitespaceis the one part of this PR that is not strictly the bugfix. It is here because the triage comment on the issue asks for the lenient
comparison to stay available behind an explicit flag, and without it this change
removes a behaviour and leaves nothing in its place. It is about ten isolated
lines — happy to drop it and keep the fix minimal if you would rather.
It deliberately has no
-wshort form: in GNUdiff,-wmeans "ignore allwhite space", which is a broader thing than what this does.
Test plan
cargo fmt --all --check && cargo clippy --all-targets && cargo test(clippy clean; see note below on two pre-existing flaky tests)
src/cmds/git/diff_cmd.rs: CRLF vs LF, missing finalnewline, trailing space, byte-identical CRLF files, and both
--ignore-whitespacepaths. They fail ondevelopand pass here.Two tests (
core::tracking::tests::test_timed_execution_*andcmds::dotnet::dotnet_trx::tests::test_parse_trx_files_in_dir_since_ignores_older_files)fail intermittently on
cargo test --allin my environment and pass when run ontheir own. They are unrelated to this change — different runs fail on different
tests, and nothing here touches tracking or dotnet.
Docs
docs/usage/FEATURES.md— added the--ignore-whitespaceoption and a note onthe byte-accurate comparison and exit codes.