diff --git a/packages/diffs/src/utils/resolveRegion.ts b/packages/diffs/src/utils/resolveRegion.ts index e3b9b8c77..3b9783c0e 100644 --- a/packages/diffs/src/utils/resolveRegion.ts +++ b/packages/diffs/src/utils/resolveRegion.ts @@ -74,22 +74,18 @@ export function resolveRegion( const updatesEOFState = hunkIndex === hunks.length - 1 && endContentIndex === currentHunk.hunkContent.length - 1; + const shouldProcessCollapsedContext = !diff.isPartial; for (const [index, hunk] of hunks.entries()) { - pushCollapsedContextLines( + processCollapsedContext( + diff, resolvedDiff, - deletionLines, - additionLines, + cursor, hunk.deletionLineIndex - hunk.collapsedBefore, hunk.additionLineIndex - hunk.collapsedBefore, - hunk.collapsedBefore + hunk.collapsedBefore, + shouldProcessCollapsedContext ); - cursor.nextAdditionLineIndex += hunk.collapsedBefore; - cursor.nextDeletionLineIndex += hunk.collapsedBefore; - cursor.nextAdditionStart += hunk.collapsedBefore; - cursor.nextDeletionStart += hunk.collapsedBefore; - cursor.splitLineCount += hunk.collapsedBefore; - cursor.unifiedLineCount += hunk.collapsedBefore; const newHunk: Hunk = { ...hunk, @@ -236,6 +232,41 @@ function pushCollapsedContextLines( } } +// Partial patches track omitted context in `collapsedBefore`, but those lines do +// not exist in the diff's line arrays. Keep the virtual row counts and file +// positions in sync without inventing hidden lines. +function processCollapsedContext( + sourceDiff: FileDiffMetadata, + resolvedDiff: FileDiffMetadata, + cursor: CursorState, + deletionLineIndex: number, + additionLineIndex: number, + lineCount: number, + shouldProcessContent: boolean +) { + if (lineCount <= 0) { + return; + } + + if (shouldProcessContent) { + pushCollapsedContextLines( + resolvedDiff, + sourceDiff.deletionLines, + sourceDiff.additionLines, + deletionLineIndex, + additionLineIndex, + lineCount + ); + cursor.nextAdditionLineIndex += lineCount; + cursor.nextDeletionLineIndex += lineCount; + } + + cursor.nextAdditionStart += lineCount; + cursor.nextDeletionStart += lineCount; + cursor.splitLineCount += lineCount; + cursor.unifiedLineCount += lineCount; +} + function pushContentLinesToDiff( content: ContextContent | ChangeContent, diff: FileDiffMetadata, diff --git a/packages/diffs/test/diffAcceptRejectHunk.test.ts b/packages/diffs/test/diffAcceptRejectHunk.test.ts index 6732b9b0a..20692036f 100644 --- a/packages/diffs/test/diffAcceptRejectHunk.test.ts +++ b/packages/diffs/test/diffAcceptRejectHunk.test.ts @@ -8,6 +8,7 @@ import type { import { diffAcceptRejectHunk } from '../src/utils/diffAcceptRejectHunk'; import { parseDiffFromFile } from '../src/utils/parseDiffFromFile'; import { parseMergeConflictDiffFromFile } from '../src/utils/parseMergeConflictDiffFromFile'; +import { parsePatchFiles } from '../src/utils/parsePatchFiles'; import { resolveConflict } from '../src/utils/resolveConflict'; import { verifyFileDiffHunkValues } from './testUtils'; @@ -83,6 +84,32 @@ function createFixture() { ); } +function createPartialFixture() { + const patch = `diff --git a/index.html b/index.html +index 36c553c..711c67c 100644 +--- a/index.html ++++ b/index.html +@@ -6,8 +6,9 @@ + +
+Thanks for visiting
++We're glad you're here
++ Learn More +