fix: Improve handling of escaped markers in apply_diff (#2274)

* fix: Improve handling of escaped markers in apply_diff

unescapeMarkers() is supposed to fix escaped merge conflict markers so
that they match the code. However the function has a bug which requires
SEARCH and REPLACE strings in the markers to be replaced. This is not
part of merge conflict markers, so many valid cases were previously
missed.

* Revert test changes

* Add new test

---------

Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com>
This commit is contained in:
Povilas Kanapickas 2025-04-04 07:46:51 +03:00 committed by GitHub
parent 7eea755703
commit 50eed96087
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 21 additions and 2 deletions

View file

@ -1436,6 +1436,25 @@ function five() {
expect(result.success).toBe(true)
})
it("handles escaping of markers with custom suffixes", async () => {
const originalContent = "before\n<<<<<<< HEAD\nmiddle\n>>>>>>> feature-branch\nafter\n"
const diffContent =
"<<<<<<< SEARCH\n" +
"before\n" +
"\\<<<<<<< HEAD\n" +
"middle\n" +
"\\>>>>>>> feature-branch\n" +
"after\n" +
"=======\n" +
"replaced content\n" +
">>>>>>> REPLACE"
const result = await strategy.applyDiff(originalContent, diffContent)
expect(result.success).toBe(true)
if (result.success) {
expect(result.content).toBe("replaced content\n")
}
})
it("detects separator when expecting replace", () => {
const diff = "<<<<<<< SEARCH\n" + "content\n" + "=======\n" + "new content\n" + "======="
const result = strategy["validateMarkerSequencing"](diff)

View file

@ -143,9 +143,9 @@ Only use a single line of '=======' between search and replacement content, beca
private unescapeMarkers(content: string): string {
return content
.replace(/^\\<<<<<<< SEARCH/gm, "<<<<<<< SEARCH")
.replace(/^\\<<<<<<</gm, "<<<<<<<")
.replace(/^\\=======/gm, "=======")
.replace(/^\\>>>>>>> REPLACE/gm, ">>>>>>> REPLACE")
.replace(/^\\>>>>>>>/gm, ">>>>>>>")
.replace(/^\\-------/gm, "-------")
.replace(/^\\:end_line:/gm, ":end_line:")
.replace(/^\\:start_line:/gm, ":start_line:")