(opts: DiffWithDeps)
| 145 | // ref-to-ref mode walks the union of both trees' files. Both |
| 146 | // yield `DiffEntry`s with each side's text resolved. |
| 147 | async function collectDiffEntries(opts: DiffWithDeps): Promise<DiffEntry[]> { |
| 148 | const dir = opts.dir ?? "/"; |
| 149 | const ref = opts.ref ?? "HEAD"; |
| 150 | |
| 151 | if (opts.to !== undefined) { |
| 152 | return collectRefToRef(opts, dir, ref, opts.to); |
| 153 | } |
| 154 | |
| 155 | let head: string; |
| 156 | try { |
| 157 | head = await opts.git.resolveRef({ fs: opts.fs, dir, ref }); |
| 158 | } catch { |
| 159 | // Ref unresolvable (e.g. workspace never cloned). An empty |
| 160 | // change set is a more useful signal than an exception for |
| 161 | // the common "diff after maybe-no-op" call site. |
| 162 | return []; |
| 163 | } |
| 164 | |
| 165 | // Pass `ref` through so the matrix is computed against the |
| 166 | // requested commit rather than always HEAD. Without this the |
| 167 | // `ref` argument would only affect blob reads, leaving the |
| 168 | // status walk silently skewed. |
| 169 | const status = await opts.git.statusMatrix({ fs: opts.fs, dir, ref, cache: opts.cache }); |
| 170 | const pathFilter = makePathFilter(opts.paths); |
| 171 | const entries: DiffEntry[] = []; |
| 172 | for (const [filepath, headStatus, workdirStatus] of status) { |
| 173 | // workdirStatus: 0 absent, 1 == HEAD, 2 differs. Skip |
| 174 | // unchanged rows up front to avoid the blob/file reads. |
| 175 | if (workdirStatus === 1) continue; |
| 176 | if (!pathFilter(filepath)) continue; |
| 177 | |
| 178 | const oldText = |
| 179 | headStatus === 1 |
| 180 | ? await readBlobAsText(opts.git, opts.fs, dir, head, filepath, opts.cache) |
| 181 | : ""; |
| 182 | const newText = |
| 183 | workdirStatus === 2 ? await readWorkdirAsText(opts.readFile, dir, filepath) : ""; |
| 184 | // headStatus 0 -> not in the base -> added. workdirStatus 0 |
| 185 | // -> gone from the working tree -> deleted. Otherwise it's a |
| 186 | // content change. |
| 187 | const status: DiffEntry["status"] = headStatus === 0 ? "A" : workdirStatus === 0 ? "D" : "M"; |
| 188 | entries.push({ path: filepath, status, oldText, newText }); |
| 189 | } |
| 190 | return entries; |
| 191 | } |
| 192 | |
| 193 | // Ref-to-ref collector. Walk the union of both commits' file |
| 194 | // lists — git's own object database, no working-tree probes — |
no test coverage detected