| author | |
| committer | |
| log | 10395bcc59707302c1476e19186532ff5a9d3557 |
| tree | d30377b01ff7f502bc05e1db1abdc15430152182 |
| parent | b77108bc41506ad7ba28839d9a8e04ba79fe340b |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Braulio Oliveira <brauliobo@gmail.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>2 files changed, 28 insertions(+), 1 deletions(-)
apps/server/src/vcs/GitVcsDriverCore.test.ts+22| ... | ... | @@ -2159,6 +2159,28 @@ it.layer(layerTest)("GitVcsDriver core integration", (it) => { |
| 2159 | 2159 | }), |
| 2160 | 2160 | ); |
| 2161 | 2161 | |
| 2162 | it.effect("skips Changes totals instead of indexing thousands of untracked files", () => | |
| 2163 | Effect.gen(function* () { | |
| 2164 | const cwd = yield* makeTmpDir(); | |
| 2165 | yield* initRepoWithCommit(cwd); | |
| 2166 | const driver = yield* GitVcsDriver.GitVcsDriver; | |
| 2167 | yield* Effect.forEach( | |
| 2168 | Array.from({ length: 5_001 }, (_, index) => `bulk/${index}.txt`), | |
| 2169 | (file) => writeTextFile(cwd, file, "x\n"), | |
| 2170 | { concurrency: 32, discard: true }, | |
| 2171 | ); | |
| 2172 | yield* writeTextFile(cwd, "README.md", "changed\n"); | |
| 2173 | ||
| 2174 | const status = yield* driver.statusDetailsLocal(cwd, { includeBranchChanges: true }); | |
| 2175 | assert.isTrue(status.hasWorkingTreeChanges); | |
| 2176 | assert.isUndefined(status.branchChanges); | |
| 2177 | ||
| 2178 | const preview = yield* driver.getReviewDiffPreview({ cwd }); | |
| 2179 | assert.isNotEmpty(preview.sources); | |
| 2180 | assert.isTrue(preview.sources.every((source) => source.truncated)); | |
| 2181 | }), | |
| 2182 | ); | |
| 2183 | ||
| 2162 | 2184 | it.effect("Changes does not show newer base commits as deletions", () => |
| 2163 | 2185 | Effect.gen(function* () { |
| 2164 | 2186 | const cwd = yield* makeTmpDir(); |
apps/server/src/vcs/GitVcsDriverCore.ts+6-1| ... | ... | @@ -59,6 +59,10 @@ const RANGE_DIFF_SUMMARY_MAX_OUTPUT_BYTES = 19_000; |
| 59 | 59 | const RANGE_DIFF_PATCH_MAX_OUTPUT_BYTES = 59_000; |
| 60 | 60 | const REVIEW_DIFF_PATCH_MAX_OUTPUT_BYTES = 120_000; |
| 61 | 61 | const REVIEW_METADATA_MAX_OUTPUT_BYTES = 16 * 1024 * 1024; |
| 62 | // Every status refresh adds the untracked files to a temporary index, and git add's cost grows | |
| 63 | // much faster than the file count (50k files took about 30 seconds). Past this many, the | |
| 64 | // totals are reported incomplete instead. | |
| 65 | const REVIEW_UNTRACKED_MAX_FILES = 5_000; | |
| 62 | 66 | const REVIEW_DIFF_FILE_MAX_OUTPUT_BYTES = 1024 * 1024; |
| 63 | 67 | // Patches the clients render are parsed against git's default a/ and b/ path |
| 64 | 68 | // prefixes. A repository or global diff.noprefix or diff.mnemonicPrefix would |
| ... | ... | @@ -2618,7 +2622,7 @@ export const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* |
| 2618 | 2622 | }); |
| 2619 | 2623 | |
| 2620 | 2624 | // Lists untracked files and adds them to a temporary index, so a diff against any commit |
| 2621 | // shows them as new. Returns null when the list is too big to read. Needs a Scope. | |
| 2625 | // shows them as new. Returns null when the list is too big to read or to index. Needs a Scope. | |
| 2622 | 2626 | const prepareUntrackedReviewIndex = Effect.fn("prepareUntrackedReviewIndex")(function* ( |
| 2623 | 2627 | cwd: string, |
| 2624 | 2628 | pathArgs: ReadonlyArray<string>, |
| ... | ... | @@ -2640,6 +2644,7 @@ export const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* |
| 2640 | 2644 | (candidate) => onlyPath === undefined || candidate === onlyPath, |
| 2641 | 2645 | ); |
| 2642 | 2646 | if (paths.length === 0) return { env: undefined }; |
| 2647 | if (paths.length > REVIEW_UNTRACKED_MAX_FILES) return null; | |
| 2643 | 2648 | const env = yield* prepareReviewIndex(cwd, paths).pipe( |
| 2644 | 2649 | Effect.catchTags({ |
| 2645 | 2650 | PlatformError: (cause) => |