mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
fix(cli): cache diffFull and ignore legacy local storage to prevent redundant git processes (#8400)
This commit is contained in:
@@ -31,6 +31,8 @@ export namespace FileIgnore {
|
||||
"mypy_cache",
|
||||
".history",
|
||||
".gradle",
|
||||
".kilocode", // kilocode_change — ignore legacy local storage (#8379)
|
||||
".opencode", // kilocode_change — ignore legacy local storage (#8379)
|
||||
])
|
||||
|
||||
const FILES = [
|
||||
|
||||
@@ -187,8 +187,31 @@ export namespace Snapshot {
|
||||
ref: "FileDiff",
|
||||
})
|
||||
export type FileDiff = z.infer<typeof FileDiff>
|
||||
|
||||
// kilocode_change start — cache diffFull results to prevent redundant git spawning (#8379)
|
||||
const diffCache = new Map<string, Promise<FileDiff[]>>()
|
||||
const DIFF_CACHE_MAX = 100
|
||||
|
||||
export async function diffFull(from: string, to: string): Promise<FileDiff[]> {
|
||||
if (from === to) return []
|
||||
const key = `${from}:${to}`
|
||||
const cached = diffCache.get(key)
|
||||
if (cached) return cached
|
||||
if (diffCache.size >= DIFF_CACHE_MAX) {
|
||||
const first = diffCache.keys().next().value
|
||||
if (first) diffCache.delete(first)
|
||||
}
|
||||
const pending = diffFullUncached(from, to).catch((err) => {
|
||||
diffCache.delete(key)
|
||||
throw err
|
||||
})
|
||||
diffCache.set(key, pending)
|
||||
return pending
|
||||
}
|
||||
|
||||
async function diffFullUncached(from: string, to: string): Promise<FileDiff[]> {
|
||||
const git = await KiloSnapshot.prepare() // kilocode_change
|
||||
// kilocode_change end
|
||||
const result: FileDiff[] = []
|
||||
const status = new Map<string, "added" | "deleted" | "modified">()
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import { test, expect } from "bun:test"
|
||||
import { $ } from "bun"
|
||||
import { Snapshot } from "../../src/snapshot"
|
||||
import { Instance } from "../../src/project/instance"
|
||||
import { Filesystem } from "../../src/util/filesystem"
|
||||
import { tmpdir } from "../fixture/fixture"
|
||||
|
||||
async function bootstrap() {
|
||||
return tmpdir({
|
||||
git: true,
|
||||
init: async (dir) => {
|
||||
await Filesystem.write(`${dir}/a.txt`, "A")
|
||||
await Filesystem.write(`${dir}/b.txt`, "B")
|
||||
await $`git add .`.cwd(dir).quiet()
|
||||
await $`git commit --no-gpg-sign -m init`.cwd(dir).quiet()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
test("diffFull returns cached result for same hash pair", async () => {
|
||||
await using tmp = await bootstrap()
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const before = await Snapshot.track()
|
||||
expect(before).toBeTruthy()
|
||||
|
||||
await Filesystem.write(`${tmp.path}/a.txt`, "MODIFIED")
|
||||
const after = await Snapshot.track()
|
||||
expect(after).toBeTruthy()
|
||||
expect(after).not.toBe(before)
|
||||
|
||||
const first = await Snapshot.diffFull(before!, after!)
|
||||
const second = await Snapshot.diffFull(before!, after!)
|
||||
|
||||
// Should be the exact same array reference (cached)
|
||||
expect(second).toBe(first)
|
||||
expect(first.length).toBeGreaterThan(0)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test("diffFull returns empty array when from === to", async () => {
|
||||
await using tmp = await bootstrap()
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const hash = await Snapshot.track()
|
||||
expect(hash).toBeTruthy()
|
||||
|
||||
const result = await Snapshot.diffFull(hash!, hash!)
|
||||
expect(result).toEqual([])
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test("diffFull concurrent calls for same pair share one result", async () => {
|
||||
await using tmp = await bootstrap()
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const before = await Snapshot.track()
|
||||
expect(before).toBeTruthy()
|
||||
|
||||
await Filesystem.write(`${tmp.path}/a.txt`, "CONCURRENT")
|
||||
const after = await Snapshot.track()
|
||||
expect(after).toBeTruthy()
|
||||
|
||||
// Fire multiple concurrent calls — they should all resolve to the same object
|
||||
const results = await Promise.all([
|
||||
Snapshot.diffFull(before!, after!),
|
||||
Snapshot.diffFull(before!, after!),
|
||||
Snapshot.diffFull(before!, after!),
|
||||
])
|
||||
|
||||
expect(results[0]).toBe(results[1])
|
||||
expect(results[1]).toBe(results[2])
|
||||
expect(results[0].length).toBeGreaterThan(0)
|
||||
},
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user