mirror of
https://fastgit.cc/https://github.com/anomalyco/opencode
synced 2026-05-03 07:11:31 +08:00
Compare commits
2 Commits
kit/cli-ef
...
fix/snapsh
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ab0d6a6c9 | ||
|
|
1f279cd2c8 |
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"nodeModules": {
|
||||
"x86_64-linux": "sha256-3VYF84QGROFpwBCYDEWHDpRFkSHwmiVWQJR81/bqjYo=",
|
||||
"aarch64-linux": "sha256-k12n4GqrjBqKqBvLjzXQhDxbc8ZMZ/1TenDp2pKh888=",
|
||||
"aarch64-darwin": "sha256-OCRX1VC5SJmrXk7whl6bsdmlRwjARGw+4RSk8c59N10=",
|
||||
"x86_64-darwin": "sha256-l+g/cMREarOVIK3a01+csC3Mk3ZfMVWAiAosSA5/U6Y="
|
||||
"x86_64-linux": "sha256-gdS7MkWGeVO0qLs0HKD156YE0uCk5vWeYjKu4JR1Apw=",
|
||||
"aarch64-linux": "sha256-tF4pyVqzbrvdkRG23Fot37FCg8guRZkcU738fHPr/OQ=",
|
||||
"aarch64-darwin": "sha256-FugTWzGMb2ktAbNwQvWRM3GWOb5RTR++8EocDDrQMLc=",
|
||||
"x86_64-darwin": "sha256-jpe6EiwKr+CS00cn0eHwcDluO4LvO3t/5l/LcFBBKP0="
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,11 +91,15 @@ export namespace Snapshot {
|
||||
const args = (cmd: string[]) => ["--git-dir", state.gitdir, "--work-tree", state.worktree, ...cmd]
|
||||
|
||||
const git = Effect.fnUntraced(
|
||||
function* (cmd: string[], opts?: { cwd?: string; env?: Record<string, string> }) {
|
||||
function* (
|
||||
cmd: string[],
|
||||
opts?: { cwd?: string; env?: Record<string, string>; stdin?: Stream.Stream<Uint8Array> },
|
||||
) {
|
||||
const proc = ChildProcess.make("git", cmd, {
|
||||
cwd: opts?.cwd,
|
||||
env: opts?.env,
|
||||
extendEnv: true,
|
||||
stdin: opts?.stdin ?? "ignore",
|
||||
})
|
||||
const handle = yield* spawner.spawn(proc)
|
||||
const [text, stderr] = yield* Effect.all(
|
||||
@@ -150,65 +154,26 @@ export namespace Snapshot {
|
||||
|
||||
const add = Effect.fnUntraced(function* () {
|
||||
yield* sync()
|
||||
const [diff, other] = yield* Effect.all(
|
||||
const list = yield* git(
|
||||
[
|
||||
git([...quote, ...args(["diff-files", "--name-only", "-z", "--", "."])], {
|
||||
cwd: state.directory,
|
||||
}),
|
||||
git([...quote, ...args(["ls-files", "--others", "--exclude-standard", "-z", "--", "."])], {
|
||||
cwd: state.directory,
|
||||
}),
|
||||
...quote,
|
||||
...args(["ls-files", "--modified", "--deleted", "--others", "--exclude-standard", "-z", "--", "."]),
|
||||
],
|
||||
{ concurrency: 2 },
|
||||
{ cwd: state.directory },
|
||||
)
|
||||
if (diff.code !== 0 || other.code !== 0) {
|
||||
if (list.code !== 0) {
|
||||
log.warn("failed to list snapshot files", {
|
||||
diffCode: diff.code,
|
||||
diffStderr: diff.stderr,
|
||||
otherCode: other.code,
|
||||
otherStderr: other.stderr,
|
||||
exitCode: list.code,
|
||||
stderr: list.stderr,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const tracked = diff.text.split("\0").filter(Boolean)
|
||||
const untracked = other.text.split("\0").filter(Boolean)
|
||||
const all = Array.from(new Set([...tracked, ...untracked]))
|
||||
if (!all.length) return
|
||||
|
||||
// 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",
|
||||
path.join(state.worktree, ".git"),
|
||||
"--work-tree",
|
||||
state.worktree,
|
||||
"check-ignore",
|
||||
"--no-index",
|
||||
"--",
|
||||
...all,
|
||||
]
|
||||
const check = yield* git(checkArgs, { cwd: state.directory })
|
||||
const ignored =
|
||||
check.code === 0 ? new Set(check.text.trim().split("\n").filter(Boolean)) : new Set<string>()
|
||||
const filtered = all.filter((item) => !ignored.has(item))
|
||||
|
||||
// Remove newly-ignored files from snapshot index to prevent re-adding
|
||||
if (ignored.size > 0) {
|
||||
const ignoredFiles = Array.from(ignored)
|
||||
log.info("removing gitignored files from snapshot", { count: ignoredFiles.length })
|
||||
yield* git([...cfg, ...args(["rm", "--cached", "-f", "--", ...ignoredFiles])], {
|
||||
cwd: state.directory,
|
||||
})
|
||||
}
|
||||
|
||||
if (!filtered.length) return
|
||||
const files = list.text.split("\0").filter(Boolean)
|
||||
if (!files.length) return
|
||||
|
||||
const large = (yield* Effect.all(
|
||||
filtered.map((item) =>
|
||||
files.map((item) =>
|
||||
fs
|
||||
.stat(path.join(state.directory, item))
|
||||
.pipe(Effect.catch(() => Effect.void))
|
||||
@@ -223,12 +188,45 @@ export namespace Snapshot {
|
||||
{ concurrency: 8 },
|
||||
)).filter((item): item is string => Boolean(item))
|
||||
yield* sync(large)
|
||||
const result = yield* git([...cfg, ...args(["add", "--sparse", "."])], { cwd: state.directory })
|
||||
|
||||
// Snapshot the current index before git add mutates it.
|
||||
// Tracked files that are now ignored still get staged by git add;
|
||||
// we reset just those entries back to this tree afterward.
|
||||
const [prev, keep] = yield* Effect.all(
|
||||
[
|
||||
git(args(["write-tree"]), { cwd: state.directory }),
|
||||
git([...quote, ...args(["ls-files", "-ci", "--exclude-standard", "-z", "--", "."])], {
|
||||
cwd: state.directory,
|
||||
}),
|
||||
],
|
||||
{ concurrency: 2 },
|
||||
)
|
||||
|
||||
const result = yield* git([...cfg, ...args(["add", "--all", "--sparse", "."])], { cwd: state.directory })
|
||||
if (result.code !== 0) {
|
||||
log.warn("failed to add snapshot files", {
|
||||
exitCode: result.code,
|
||||
stderr: result.stderr,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const base = prev.code === 0 ? prev.text.trim() : ""
|
||||
const cached = keep.code === 0 ? keep.text : ""
|
||||
if (!base || !cached) return
|
||||
|
||||
const reset = yield* git(
|
||||
[...cfg, ...args(["reset", "-q", "--pathspec-from-file=-", "--pathspec-file-nul", base])],
|
||||
{
|
||||
cwd: state.directory,
|
||||
stdin: Stream.make(new TextEncoder().encode(cached)),
|
||||
},
|
||||
)
|
||||
if (reset.code !== 0) {
|
||||
log.warn("failed to reset ignored snapshot files", {
|
||||
exitCode: reset.code,
|
||||
stderr: reset.stderr,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -295,30 +293,6 @@ export namespace Snapshot {
|
||||
.map((x) => x.trim())
|
||||
.filter(Boolean)
|
||||
|
||||
// Filter out files that are now gitignored
|
||||
if (files.length > 0) {
|
||||
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 = files.filter((item) => !ignored.has(item))
|
||||
return {
|
||||
hash,
|
||||
files: filtered.map((x) => path.join(state.worktree, x).replaceAll("\\", "/")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
hash,
|
||||
files: files.map((x) => path.join(state.worktree, x).replaceAll("\\", "/")),
|
||||
@@ -672,29 +646,6 @@ export namespace Snapshot {
|
||||
]
|
||||
})
|
||||
|
||||
// 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 }))
|
||||
|
||||
Reference in New Issue
Block a user