Skip to content

Commit 35fbb01

Browse files
authored
fix: Diff view now ignores line endings changes/windows autocrlf (#4356)
1 parent 6527a12 commit 35fbb01

3 files changed

Lines changed: 34 additions & 13 deletions

File tree

packages/opencode/src/cli/cmd/tui/context/theme.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,18 +864,21 @@ function generateSyntax(theme: Theme) {
864864
scope: ["diff.plus"],
865865
style: {
866866
foreground: theme.diffAdded,
867+
background: theme.diffAddedBg,
867868
},
868869
},
869870
{
870871
scope: ["diff.minus"],
871872
style: {
872873
foreground: theme.diffRemoved,
874+
background: theme.diffRemovedBg,
873875
},
874876
},
875877
{
876878
scope: ["diff.delta"],
877879
style: {
878880
foreground: theme.diffContext,
881+
background: theme.diffContextBg,
879882
},
880883
},
881884
{

packages/opencode/src/snapshot/index.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export namespace Snapshot {
2424
})
2525
.quiet()
2626
.nothrow()
27+
// Configure git to not convert line endings on Windows
28+
await $`git --git-dir ${git} config core.autocrlf false`.quiet().nothrow()
2729
log.info("initialized")
2830
}
2931
await $`git --git-dir ${git} --work-tree ${Instance.worktree} add .`.quiet().cwd(Instance.directory).nothrow()
@@ -45,10 +47,11 @@ export namespace Snapshot {
4547
export async function patch(hash: string): Promise<Patch> {
4648
const git = gitdir()
4749
await $`git --git-dir ${git} --work-tree ${Instance.worktree} add .`.quiet().cwd(Instance.directory).nothrow()
48-
const result = await $`git --git-dir ${git} --work-tree ${Instance.worktree} diff --name-only ${hash} -- .`
49-
.quiet()
50-
.cwd(Instance.directory)
51-
.nothrow()
50+
const result =
51+
await $`git -c core.autocrlf=false --git-dir ${git} --work-tree ${Instance.worktree} diff --name-only ${hash} -- .`
52+
.quiet()
53+
.cwd(Instance.directory)
54+
.nothrow()
5255

5356
// If git diff fails, return empty patch
5457
if (result.exitCode !== 0) {
@@ -122,10 +125,11 @@ export namespace Snapshot {
122125
export async function diff(hash: string) {
123126
const git = gitdir()
124127
await $`git --git-dir ${git} --work-tree ${Instance.worktree} add .`.quiet().cwd(Instance.directory).nothrow()
125-
const result = await $`git --git-dir ${git} --work-tree ${Instance.worktree} diff ${hash} -- .`
126-
.quiet()
127-
.cwd(Instance.worktree)
128-
.nothrow()
128+
const result =
129+
await $`git -c core.autocrlf=false --git-dir ${git} --work-tree ${Instance.worktree} diff ${hash} -- .`
130+
.quiet()
131+
.cwd(Instance.worktree)
132+
.nothrow()
129133

130134
if (result.exitCode !== 0) {
131135
log.warn("failed to get diff", {
@@ -155,7 +159,7 @@ export namespace Snapshot {
155159
export async function diffFull(from: string, to: string): Promise<FileDiff[]> {
156160
const git = gitdir()
157161
const result: FileDiff[] = []
158-
for await (const line of $`git --git-dir ${git} --work-tree ${Instance.worktree} diff --no-renames --numstat ${from} ${to} -- .`
162+
for await (const line of $`git -c core.autocrlf=false --git-dir ${git} --work-tree ${Instance.worktree} diff --no-renames --numstat ${from} ${to} -- .`
159163
.quiet()
160164
.cwd(Instance.directory)
161165
.nothrow()
@@ -165,10 +169,16 @@ export namespace Snapshot {
165169
const isBinaryFile = additions === "-" && deletions === "-"
166170
const before = isBinaryFile
167171
? ""
168-
: await $`git --git-dir ${git} --work-tree ${Instance.worktree} show ${from}:${file}`.quiet().nothrow().text()
172+
: await $`git -c core.autocrlf=false --git-dir ${git} --work-tree ${Instance.worktree} show ${from}:${file}`
173+
.quiet()
174+
.nothrow()
175+
.text()
169176
const after = isBinaryFile
170177
? ""
171-
: await $`git --git-dir ${git} --work-tree ${Instance.worktree} show ${to}:${file}`.quiet().nothrow().text()
178+
: await $`git -c core.autocrlf=false --git-dir ${git} --work-tree ${Instance.worktree} show ${to}:${file}`
179+
.quiet()
180+
.nothrow()
181+
.text()
172182
result.push({
173183
file,
174184
before,

packages/opencode/src/tool/edit.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ import { Instance } from "../project/instance"
1818
import { Agent } from "../agent/agent"
1919
import { Snapshot } from "@/snapshot"
2020

21+
function normalizeLineEndings(text: string): string {
22+
return text.replaceAll("\r\n", "\n")
23+
}
24+
2125
export const EditTool = Tool.define("edit", {
2226
description: DESCRIPTION,
2327
parameters: z.object({
@@ -91,7 +95,9 @@ export const EditTool = Tool.define("edit", {
9195
contentOld = await file.text()
9296
contentNew = replace(contentOld, params.oldString, params.newString, params.replaceAll)
9397

94-
diff = trimDiff(createTwoFilesPatch(filePath, filePath, contentOld, contentNew))
98+
diff = trimDiff(
99+
createTwoFilesPatch(filePath, filePath, normalizeLineEndings(contentOld), normalizeLineEndings(contentNew)),
100+
)
95101
if (agent.permission.edit === "ask") {
96102
await Permission.ask({
97103
type: "edit",
@@ -111,7 +117,9 @@ export const EditTool = Tool.define("edit", {
111117
file: filePath,
112118
})
113119
contentNew = await file.text()
114-
diff = trimDiff(createTwoFilesPatch(filePath, filePath, contentOld, contentNew))
120+
diff = trimDiff(
121+
createTwoFilesPatch(filePath, filePath, normalizeLineEndings(contentOld), normalizeLineEndings(contentNew)),
122+
)
115123
})()
116124

117125
FileTime.read(ctx.sessionID, filePath)

0 commit comments

Comments
 (0)