Skip to content

fix(repo): force LF for the lib snapshot inputs so Windows checkouts - #19

Merged
t3dotgg merged 2 commits into
pingdotgg:mainfrom
DeryFerd:fix/gitattributes-lf
Oct 9, 2026
Merged

t3dotgg merged 2 commits into
pingdotgg:mainfrom
DeryFerd:fix/gitattributes-lf

Conversation

@DeryFerd

@DeryFerd DeryFerd commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Problem

On Windows the lib_bind.bin and lib_parse.bin snapshots never match, so cargo test -p ts_goport --lib fails snapshot_matches_live_bind and snapshot_matches_live_parse on every checkout, out of the box. The cause is line endings. Each snapshot keys its sections with a hash of the bytes of the files it reads at build time, and a default Windows checkout (core.autocrlf=true) rewrites those files to CRLF, so none of the keys match the blobs.

What the keys hash

The keys are not a hash of the lib text alone. crates/ts_goport/src/frontend/parser/lib_parse_snapshot.rs and crates/ts_goport/src/binder/lib_snapshot.rs fold a SOURCES_HASH into every key, and SOURCES_HASH is a compile-time hash of the parser, scanner, factory, store, node, core.rs, flags.rs and lib-name sources, read with include_bytes!. The lib text comes in separately through include_str! in crates/ts_goport/src/frontend/bundled/embed.rs, and both the text hash and its const_hash go into the same key. All of this reads the working tree rather than the index, so a checkout that rewrites text files to CRLF changes every key at once.

The change

.gitattributes now forces LF in the working tree for the files those keys read:

  • *.rs
  • crates/ts_goport/libs/*.d.ts

The index already holds LF for all of them, so this changes no committed bytes. It only stops a Windows checkout from rewriting them. The three files the repo keeps as CRLF on purpose are left alone: crates/ts_goport/tests/fixtures/source_map_cut/case/parserSkippedTokens16.ts and the two licenses/ files.

Why the libs alone are not enough

Pinning only crates/ts_goport/libs/*.d.ts is not sufficient. It fixes the text and text_const parts of the key, so snapshot_matches_live_bind passes, but snapshot_matches_live_parse still fails on its sources field, which hashes the .rs sources. Both rules are needed before both tests pass.

Verification

On Windows, with rustc stable and core.autocrlf=true:

  • cargo check -p ts_goport --lib passes.
  • cargo fmt --all -- --check passes.
  • cargo test -p ts_goport --lib goes from 278 passed / 5 failed to 280 passed / 3 failed. The two tests this fixes are binder::lib_snapshot::tests::snapshot_matches_live_bind and frontend::parser::lib_parse_snapshot::tests::snapshot_matches_live_parse.

The three that still fail are unrelated to line endings and are not touched by this change:

  • execute::build::config_prefetch::tests::panic_after_parse_reaches_take builds a temp path with Windows backslashes.
  • format::api_test::test_format_format_checker_ts needs the pinned Go checkout (TS_GO_REPO), which is not present.
  • project::logging::logger::tests::log_time_is_local_time re-runs itself with TZ=Etc/GMT+7 and reads /proc/self/exe, so it is Linux-only.

Compatibility

On Linux and macOS the checkouts are already LF, so the rules are a no-op there and CI is unaffected. The rules only guarantee the working tree stays LF regardless of a contributor's core.autocrlf setting.

Note

Force LF line endings for lib snapshot input files

Adds LF end-of-line rules for Rust files and TypeScript declaration files under crates/ts_goport/libs in .gitattributes. This keeps the byte representation stable for snapshot hash inputs on Windows checkouts. Existing custom merge drivers are unchanged.

Macroscope summarized 3faa37f.

Summary by CodeRabbit

  • Chores
    • Standardized working-tree line endings for Rust files and TypeScript declaration snapshots. No user-facing behavior changed.

…match

The lib_bind.bin and lib_parse.bin snapshots key their sections by a
compile-time hash of the bytes of their inputs: the bundled libs read
through include_str!, and the parser/binder sources read through
include_bytes! (SOURCES_HASH in frontend/parser/lib_parse_snapshot.rs and
binder/lib_snapshot.rs).

Those bytes are the working-tree text, so on a checkout that rewrites text
files to CRLF (Windows with core.autocrlf=true, the default) every key
misses and two tests fail:

  - binder::lib_snapshot::tests::snapshot_matches_live_bind
  - frontend::parser::lib_parse_snapshot::tests::snapshot_matches_live_parse

Pin LF in the working tree for .rs and for the bundled libs. The index
already holds LF for all of these files, so no committed content changes;
this only stops a Windows checkout from rewriting them.

Verified: with the rule, both tests pass (280 passed, up from 278); the
three remaining lib-test failures are unrelated environment cases (a
Windows temp-path test, a test that needs TS_GO_REPO, and a Linux-only
/proc/self/exe test).
@DeryFerd DeryFerd changed the title fix(repo): force LF for the lib snapshot inputs so Windows checkouts … fix(repo): force LF for the lib snapshot inputs so Windows checkouts Oct 7, 2026
@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b2fa7772-68ab-4aa9-9a2c-2dfaf060354d

📥 Commits

Reviewing files that changed from the base of the PR and between 5877cf3 and 3faa37f.


You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c3ae1fda-2310-4e64-a03e-e6ad6a55e53e

📥 Commits

Reviewing files that changed from the base of the PR and between 5f0bc92 and 5877cf3.


📒 Files selected for processing (1)
  • .gitattributes

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.



Walkthrough

The .gitattributes file now sets LF working-tree line endings for Rust files and TypeScript declaration snapshots. Comments document how line endings affect snapshot hash matching. Existing binary merge-driver rules remain unchanged.

Changes

Line-ending attributes

Layer / File(s) Summary
LF rules and snapshot hashing
.gitattributes
The file sets LF working-tree line endings for *.rs and crates/ts_goport/libs/*.d.ts. Comments describe the snapshot hash inputs and how CRLF checkout conversion affects snapshot matching.

Priority: ⬇️ Low

Estimated code review effort: 1 (Trivial) | ~5 minutes

Change: Bug fix

Suggested reviewers: t3dotgg

Merge Risk: ⚪ Minimal · up to 5877c

The LF rules stabilize the relevant snapshot inputs without changing the intentional CRLF files, so no material merge risk is evident.

Architecture Summary

Architecture risk: 🔵 Low · up to 5877c

The changed surface does not map to a changed system, dependency edge, entrypoint, or external dependency.

Changed systems: None identified.

Architecture concerns
No architecture-level concerns identified.

Review details

Before / after behavior

  • observed — Modified behavior in .gitattributes: Added comments about snapshot hash inputs and CRLF checkout effects, plus LF line-ending attributes for *.rs and crates/ts_goport/libs/*.d.ts.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: forcing LF line endings for library snapshot inputs to fix Windows checkout issues.


✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR


  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@t3dotgg

t3dotgg commented Oct 7, 2026

Copy link
Copy Markdown
Member

Note

🤖 Claude Opus 5.5 responding on behalf of Theo

This is correct. I checked it against main (876e8c79e):

  • All 1,142 .rs and crates/ts_goport/libs/*.d.ts files are LF in the index and have no CR byte, so the rules change no committed content.
  • A checkout of main with core.autocrlf=true writes all 1,142 files as CRLF. With this PR, a fresh checkout writes them as LF, and each file is byte-equal to a Linux checkout. lib_bind.bin and lib_parse.bin are binary and stay byte-equal both ways. So SOURCES_HASH and the text keys match the committed blobs.
  • On Linux, git add --renormalize . changes nothing.
  • The merge=lib-blob lines do not change, and the new patterns do not match the .bin files.

One addition for the description: an existing Windows clone keeps its CRLF files after it pulls this change, because git does not rewrite files whose content did not change. A fresh clone fixes it. So does git rm -r --cached -q . && git reset --hard, but that drops local changes.

CI has not run yet. It is waiting for approval of a first-time contributor.

@t3dotgg

t3dotgg commented Oct 9, 2026

Copy link
Copy Markdown
Member

Note

🤖 Claude Opus 5.5 responding on behalf of Theo

Thank you, @DeryFerd. I checked this change again on the current main (17d0484f2):

  • All 1,148 .rs and crates/ts_goport/libs/*.d.ts files are LF in the index. In a fresh Linux clone, git add --renormalize . changes nothing.
  • A clone with core.autocrlf=true now writes these files as LF, byte-equal to a Linux checkout. The lib blobs stay byte-equal, and lib-blobs.sh stale finds no stale blob.
  • The merge=lib-blob lines do not change.
  • This is the LF rule that #29 needs.

I merged main into the branch. The first CI run on it failed 2 early_emit K2 tests (TS2305). That is a known test setup flake (coarse file clock) with a fix in progress, not this change. The re-run passed. Merging now.

@t3dotgg
t3dotgg merged commit f28d243 into pingdotgg:main Oct 9, 2026
6 of 7 checks passed
JakubCzarlinski pushed a commit to JakubCzarlinski/ts-rust that referenced this pull request Oct 9, 2026
…er, --singleThreaded tsc -b and watch carry ids, value_symbol_links newtype)

followups38 is main 8ac70c6 plus 7 commits, so this merge also brings
main's PR code (pingdotgg#8, pingdotgg#10, pingdotgg#19, pingdotgg#30) and the light flake fix bf57472.

Conflict: crates/ts_goport/tests/early_emit.rs.
- ours (int56, eeflake1): the full K2 test change; build_emit_only_solution
  uses Solution and waits with Solution::wait_for_a_later_mtime.
- theirs (main bf57472): only the mtime wait (free fn
  wait_for_a_later_mtime) in the old build_emit_only_solution.
Took ours, as state note main-flake-fix-2026-10-09 says (int56 carries
the full eeflake1 change, which includes the mtime wait).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants