Preserve CRLF lockfile line endings on Windows - #9669
Merged
Conversation
write_lock decided whether to emit `\r\n` from @lockfile_contents, which is read in text mode and drops carriage returns on Windows. A `\r\n` lockfile was therefore rewritten with `\n`. Detect the existing line ending from the raw bytes on disk instead, and apply the conversion after the equality check so the comparison keeps operating on `\n` content. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Keeps IO errors on the raw read mapped to Bundler friendly errors like the other file operations in write_lock. Also rename the CRLF spec descriptions that spelled the line ending backwards. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates Bundler’s lockfile writing logic to correctly preserve CRLF (\r\n) line endings (especially on Windows where text-mode reads strip \r), and adjusts specs so the CRLF preservation behavior is exercised on Windows.
Changes:
- Detect existing CRLF line endings from raw bytes on disk and apply CRLF conversion only when writing the lockfile.
- Move CRLF conversion to after the “no changes” equality check so comparisons operate on LF-normalized content.
- Update lockfile specs to run on Windows and use
File.binreadwhen asserting CRLF presence.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| spec/lock/lockfile_spec.rb | Enables CRLF preservation spec on Windows and uses binary reads to correctly assert \r\n. |
| lib/bundler/definition.rb | Preserves CRLF line endings by checking raw bytes on disk and applying conversion during lockfile write. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+426
to
+432
| # Convert to \r\n if the existing lock has them, i.e., Windows with | ||
| # `git config core.autocrlf=true`. Detect from the bytes on disk because | ||
| # reading in text mode strips carriage returns on Windows, which would | ||
| # otherwise defeat this check and rewrite a `\r\n` lockfile with `\n`. | ||
| if File.exist?(file) && SharedHelpers.filesystem_access(file, :read) {|p| File.binread(p).include?("\r\n") } | ||
| contents.gsub!(/\n/, "\r\n") | ||
| end |
hsbt
added a commit
that referenced
this pull request
Jul 10, 2026
Preserve CRLF lockfile line endings on Windows (cherry picked from commit 0d35496)
hsbt
added a commit
that referenced
this pull request
Jul 10, 2026
Preserve CRLF lockfile line endings on Windows (cherry picked from commit 0d35496)
hsbt
added a commit
that referenced
this pull request
Jul 10, 2026
Preserve CRLF lockfile line endings on Windows (cherry picked from commit 0d35496)
hsbt
added a commit
that referenced
this pull request
Jul 10, 2026
Preserve CRLF lockfile line endings on Windows (cherry picked from commit 0d35496)
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.
When write_lock rewrites Gemfile.lock it decided whether to emit CRLF from the copy of the lockfile it had read into memory, but that copy is read in text mode so carriage returns are dropped on Windows and a CRLF lockfile was rewritten with LF. This now detects the existing line ending from the raw bytes on disk, and moves the conversion after the equality check so the comparison keeps operating on LF content and an untouched lockfile is preserved when nothing changed. The raw read goes through filesystem_access so its IO errors map to the same Bundler friendly errors as the other file operations in write_lock. The spec was previously skipped on Windows and now runs, reading the file in binary so text mode does not hide the carriage returns it asserts.
Forward port of the following ruby/ruby change.
ruby/ruby#17602