fix: preserve changes when diff fails
This commit is contained in:
@@ -98,6 +98,10 @@
|
||||
`changes.touched` ACK bridge; full diff/preview data stays Main-only; and
|
||||
untracked reads plus previews are both limited to 8 KiB while size/mtime
|
||||
detect equal-length changes beyond that window.
|
||||
- Closed the follow-up review finding by making per-candidate Git diff failure,
|
||||
non-zero exit, or output-limit rejection non-fatal: the Main snapshot keeps
|
||||
the changed relative path and status while omitting only the unavailable
|
||||
diff. The regression uses the same `Git output is too large` failure shape.
|
||||
- The packaged smoke now has two halves: a staged production-closure Pi
|
||||
process check and a controlled Electron-Node authenticated bridge check that
|
||||
actually executes browser status/screenshot attachment and game asset
|
||||
@@ -114,7 +118,7 @@
|
||||
`Makelore/index.tsx`; none are in this task's changed scope).
|
||||
- Final focused PI-090/Pi projection/bridge/game/resource suite: 12 files,
|
||||
71 tests passed. The planner's five minimal failure shapes are also covered
|
||||
by the 4-file 19-test tracker/bridge/runtime subset.
|
||||
by the final 4-file 20-test tracker/bridge/runtime subset.
|
||||
- Final serial full suite
|
||||
(`corepack pnpm vitest run --maxWorkers=1 --no-file-parallelism`): 203 files,
|
||||
2226 tests passed, 2 skipped. Two preceding parallel full-suite runs each
|
||||
|
||||
@@ -325,10 +325,17 @@ export class ConversationChangeTracker {
|
||||
diff?: string;
|
||||
truncated?: boolean;
|
||||
}> {
|
||||
const [working, staged] = await Promise.all([
|
||||
this.git.run(projectPath, ['diff', '--no-ext-diff', '--no-color', '--relative', '--', relativePath]),
|
||||
this.git.run(projectPath, ['diff', '--cached', '--no-ext-diff', '--no-color', '--relative', '--', relativePath]),
|
||||
]);
|
||||
let working: GitCommandResult;
|
||||
let staged: GitCommandResult;
|
||||
try {
|
||||
[working, staged] = await Promise.all([
|
||||
this.git.run(projectPath, ['diff', '--no-ext-diff', '--no-color', '--relative', '--', relativePath]),
|
||||
this.git.run(projectPath, ['diff', '--cached', '--no-ext-diff', '--no-color', '--relative', '--', relativePath]),
|
||||
]);
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
if (working.code !== 0 || staged.code !== 0) return {};
|
||||
const bounded = boundedText(`${staged.stdout}${working.stdout}`, MAX_DIFF_BYTES);
|
||||
return {
|
||||
...(bounded.text ? { diff: bounded.text } : {}),
|
||||
|
||||
@@ -143,6 +143,40 @@ describe('PI-090 product tools', () => {
|
||||
)).files).toEqual([expect.objectContaining({ path: 'notes.txt', preview: 'local notes\n' })]);
|
||||
});
|
||||
|
||||
it('keeps the changed path when a candidate diff is unavailable or oversized', async () => {
|
||||
const root = await temporaryRoot('makelore-pi-diff-unavailable-');
|
||||
await writeFile(path.join(root, 'tracked.txt'), 'changed\n', 'utf8');
|
||||
let statusReads = 0;
|
||||
const tracker = new ConversationChangeTracker({
|
||||
async run(_projectPath, args) {
|
||||
if (args[0] === 'rev-parse' && args[1] === '--is-inside-work-tree') {
|
||||
return { code: 0, stdout: 'true\n' };
|
||||
}
|
||||
if (args[0] === 'rev-parse') return { code: 0, stdout: `${'a'.repeat(40)}\n` };
|
||||
if (args[0] === 'status') {
|
||||
statusReads += 1;
|
||||
return {
|
||||
code: 0,
|
||||
stdout: statusReads === 1
|
||||
? ''
|
||||
: '1 .M N... 100644 100644 100644 abc abc tracked.txt\0',
|
||||
};
|
||||
}
|
||||
if (args[0] === 'diff') throw new Error('Git output is too large');
|
||||
throw new Error(`Unexpected Git call: ${args.join(' ')}`);
|
||||
},
|
||||
});
|
||||
await tracker.beginRun({
|
||||
conversationId: 'conversation-a', runId: 'run-a', projectPath: root,
|
||||
});
|
||||
const snapshot = await tracker.recordTouchedPaths(
|
||||
'conversation-a', 'run-a', ['tracked.txt'],
|
||||
);
|
||||
expect(snapshot.files).toEqual([{
|
||||
path: 'tracked.txt', status: 'modified',
|
||||
}]);
|
||||
});
|
||||
|
||||
it('supports no-git projects and rejects paths outside the project', async () => {
|
||||
const root = await temporaryRoot('makelore-pi-no-git-');
|
||||
await writeFile(path.join(root, 'notes.txt'), 'local notes\n', 'utf8');
|
||||
|
||||
Reference in New Issue
Block a user