Browse Source

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 <[email protected]>
Povilas Kanapickas 9 months ago
parent
commit
50eed96087

+ 19 - 0
src/core/diff/strategies/__tests__/multi-search-replace.test.ts

@@ -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)

+ 2 - 2
src/core/diff/strategies/multi-search-replace.ts

@@ -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:")