mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-19 08:09:51 +00:00
fix(snapshot): complete gitignore respect for previously tracked files (#22172)
This commit is contained in:
parent
fa2c69f09c
commit
264418c0cd
2 changed files with 62 additions and 0 deletions
|
|
@ -180,6 +180,7 @@ export namespace Snapshot {
|
|||
// Filter out files that are now gitignored even if previously tracked
|
||||
// Files may have been tracked before being gitignored, so we need to check
|
||||
// against the source project's current gitignore rules
|
||||
// Use --no-index to check purely against patterns (ignoring whether file is tracked)
|
||||
const checkArgs = [
|
||||
...quote,
|
||||
"--git-dir",
|
||||
|
|
@ -187,6 +188,7 @@ export namespace Snapshot {
|
|||
"--work-tree",
|
||||
state.worktree,
|
||||
"check-ignore",
|
||||
"--no-index",
|
||||
"--",
|
||||
...all,
|
||||
]
|
||||
|
|
@ -303,6 +305,7 @@ export namespace Snapshot {
|
|||
"--work-tree",
|
||||
state.worktree,
|
||||
"check-ignore",
|
||||
"--no-index",
|
||||
"--",
|
||||
...files,
|
||||
]
|
||||
|
|
@ -669,6 +672,30 @@ export namespace Snapshot {
|
|||
} satisfies Row,
|
||||
]
|
||||
})
|
||||
|
||||
// Filter out files that are now gitignored
|
||||
if (rows.length > 0) {
|
||||
const files = rows.map((r) => r.file)
|
||||
const checkArgs = [
|
||||
...quote,
|
||||
"--git-dir",
|
||||
path.join(state.worktree, ".git"),
|
||||
"--work-tree",
|
||||
state.worktree,
|
||||
"check-ignore",
|
||||
"--no-index",
|
||||
"--",
|
||||
...files,
|
||||
]
|
||||
const check = yield* git(checkArgs, { cwd: state.directory })
|
||||
if (check.code === 0) {
|
||||
const ignored = new Set(check.text.trim().split("\n").filter(Boolean))
|
||||
const filtered = rows.filter((r) => !ignored.has(r.file))
|
||||
rows.length = 0
|
||||
rows.push(...filtered)
|
||||
}
|
||||
}
|
||||
|
||||
const step = 100
|
||||
const patch = (file: string, before: string, after: string) =>
|
||||
formatPatch(structuredPatch(file, file, before, after, "", "", { context: Number.MAX_SAFE_INTEGER }))
|
||||
|
|
|
|||
|
|
@ -612,6 +612,41 @@ test("files tracked in snapshot but now gitignored are filtered out", async () =
|
|||
})
|
||||
})
|
||||
|
||||
test("gitignore updated between track calls filters from diff", async () => {
|
||||
await using tmp = await bootstrap()
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
// a.txt is already committed from bootstrap - track it in snapshot
|
||||
const before = await Snapshot.track()
|
||||
expect(before).toBeTruthy()
|
||||
|
||||
// Modify a.txt (so it appears in diff-files)
|
||||
await Filesystem.write(`${tmp.path}/a.txt`, "modified content")
|
||||
|
||||
// Now add gitignore that would exclude a.txt
|
||||
await Filesystem.write(`${tmp.path}/.gitignore`, "a.txt\n")
|
||||
|
||||
// Also modify b.txt which is not gitignored
|
||||
await Filesystem.write(`${tmp.path}/b.txt`, "also modified")
|
||||
|
||||
// Second track - should not include a.txt even though it changed
|
||||
const after = await Snapshot.track()
|
||||
expect(after).toBeTruthy()
|
||||
|
||||
// Verify a.txt is NOT in the diff between snapshots
|
||||
const diffs = await Snapshot.diffFull(before!, after!)
|
||||
expect(diffs.some((x) => x.file === "a.txt")).toBe(false)
|
||||
|
||||
// But .gitignore should be in the diff
|
||||
expect(diffs.some((x) => x.file === ".gitignore")).toBe(true)
|
||||
|
||||
// b.txt should be in the diff (not gitignored)
|
||||
expect(diffs.some((x) => x.file === "b.txt")).toBe(true)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test("git info exclude changes", async () => {
|
||||
await using tmp = await bootstrap()
|
||||
await Instance.provide({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue