Repository navigation
diff: Parse truncated hunks through parse options - #3688
Merged
Merged
Conversation
citizenhicks
marked this pull request as ready for review
October 25, 2026 11:51
Recognize paired unified file headers when the current hunk cannot complete, while preserving complete hunks containing header-looking source. Track hunk positions independently of source lines so empty truncated hunks still constrain ordering on both sides. Add regressions for both failures and document the ambiguous-header rule in English and Chinese. AI-assisted implementation and regression validation.
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.
Description
Add
DiffFile::parse_with(patch, DiffParseOptions)for parsing a unified or Git diff with opt-in relaxations, starting with one:truncated_hunks(true)accepts a hunk that ends before its declared line counts and counts it from the lines present.DiffFile::parseis unchanged and stays strict.Declared counts remain an upper bound, so a line beyond them is still an error, as are malformed hunk headers (including overflowing ranges), invalid paths, unordered or overlapping hunks, source lines on a missing side and combined diffs. A short hunk ends at the first line that is not a context, deletion or addition line, or at a paired unified file header when treating that pair as source cannot complete the declared hunk. A complete source interpretation takes precedence for ambiguous
---/+++lines. Hunk positions remain ordered on both sides even when a truncated hunk supplies no source lines. An empty line inside it is an empty context line, as it already is in strict parsing. Its source line numbers stay within the declared range, and the hunk's original line range covers only the lines present, soDiffHunkSeparator::LineInfocounts hidden lines from what arrived. The@@label keeps the header text as written.DiffFile::is_truncated()reports whether any hunk of the file ended early. It is alwaysfalsefor files fromparse,unchangedandparse_conflicts.English and Chinese Diff documentation describe the option.
Public API
gpui-component
diff::DiffParseOptions— Opt-in parse relaxations;Copy,Default, private fields, every relaxation off by default.diff::DiffParseOptions::new() -> Self— Options that parse exactly asDiffFile::parsedoes.diff::DiffParseOptions::truncated_hunks(self, truncated_hunks: bool) -> Self— Accept hunks that end before their declared line counts, counting them from the lines present.diff::DiffParseOptions::has_truncated_hunks(&self) -> bool— Read thetruncated_hunkssetting.diff::DiffFile::parse_with(patch: &str, options: DiffParseOptions) -> Result<Vec<DiffFile>, DiffParseError>— Parse likeparse, applying the enabled relaxations.diff::DiffFile::is_truncated(&self) -> bool— Whether a hunk of this file ended before its declared line counts.Breaking Changes
None.
DiffFile::parsekeeps its signature and strict behavior; the new items are additive.How to Test
cargo test -p gpui-component --features test-support diff cargo clippy -p gpui-component --locked -- --deny warnings cargo fmt --check -p gpui-componentNew tests in
crates/component/src/diff/parser_tests.rs:truncated_hunks_count_the_lines_present— one patch with hunks cut before the next file, before the next hunk, and at the end of the patch. Strictparserejects it.parse_withyields the lines present, additions and deletions, source line numbers, hidden lines before the following hunk, andis_truncated(); an empty line inside a short hunk is empty context; a complete hunk is not truncated.truncated_hunks_keep_structural_errors— with the option on, lines beyond the declared counts, unordered hunks, an overflowing or invalid hunk header (including a zero-count side atusize::MAX), an invalid quoted path and source lines on a missing side are still errors. A short hunk nearusize::MAXkeeps its line numbers within the declared range.non_ascii_lines_after_a_short_hunk_do_not_panic— a non-ASCII line after a short hunk returns a strict parse error or ends the accepted truncated hunk, without slicing inside a UTF-8 character.truncated_unified_hunks_stop_before_the_next_file_headers— separate files withoutdiff --git, while preserving complete hunks containing header-looking source.empty_truncated_hunks_preserve_order_on_both_sides— reject backwards positions on either side after an empty truncated hunk, while accepting forward positions.Existing strict-parser tests, including
malformed_hunks_fail_without_partial_documents, pass unchanged.Follow-up validation: both new regressions fail before the fix. After the fix,
cargo test -p gpui-component --features test-support --lib diff --lockedpassed 56 tests.cargo clippy -p gpui-component --features test-support --tests --locked -- --deny warnings,cargo fmt --all --checkandgit diff --checkpassed. The parser fixes, regression tests and bilingual documentation updates were AI-assisted.Checklist
cargo runfor story tests related to the changes.Implementation, tests and documentation were written with AI assistance and reviewed by the author.