(sessionId: string, req: FsDiffRequest)
| 132 | } |
| 133 | |
| 134 | async diff(sessionId: string, req: FsDiffRequest): Promise<FsDiffResponse> { |
| 135 | const session = await this.sessions.get(sessionId); |
| 136 | const cwd = session.metadata.cwd; |
| 137 | const realCwd = await fs.realpath(cwd); |
| 138 | const safe = await resolveSafePath(realCwd, req.path); |
| 139 | const rel = safe.relative; |
| 140 | |
| 141 | const insideRes = await runCommand('git', ['rev-parse', '--is-inside-work-tree'], realCwd); |
| 142 | if (insideRes.exitCode !== 0 || insideRes.stdout.trim() !== 'true') { |
| 143 | throw new FsGitUnavailableError( |
| 144 | realCwd, |
| 145 | insideRes.stderr.trim() || `git rev-parse exit ${insideRes.exitCode}`, |
| 146 | ); |
| 147 | } |
| 148 | |
| 149 | const statusRes = await runCommand( |
| 150 | 'git', |
| 151 | ['status', '--porcelain=v1', '--', rel], |
| 152 | realCwd, |
| 153 | ); |
| 154 | if (statusRes.exitCode !== 0) { |
| 155 | throw new FsGitUnavailableError( |
| 156 | realCwd, |
| 157 | statusRes.stderr.trim() || `git status exit ${statusRes.exitCode}`, |
| 158 | ); |
| 159 | } |
| 160 | const untracked = statusRes.stdout.startsWith('??'); |
| 161 | |
| 162 | // A repo with no commits yet has no HEAD to diff against — every changed |
| 163 | // file is all-new there, same as the untracked case. |
| 164 | const headRes = await runCommand('git', ['rev-parse', '--verify', '--quiet', 'HEAD'], realCwd); |
| 165 | const hasHead = headRes.exitCode === 0; |
| 166 | |
| 167 | // An untracked file has no HEAD side; diff it against /dev/null so the UI |
| 168 | // gets an all-added hunk. `git diff --no-index` exits 1 when files differ. |
| 169 | let diffRes: RunResult; |
| 170 | if (untracked || !hasHead) { |
| 171 | diffRes = await runCommand( |
| 172 | 'git', |
| 173 | ['diff', '--no-color', '--no-index', '--', '/dev/null', rel], |
| 174 | realCwd, |
| 175 | ); |
| 176 | if (diffRes.exitCode !== 0 && diffRes.exitCode !== 1) { |
| 177 | throw new FsGitUnavailableError( |
| 178 | realCwd, |
| 179 | diffRes.stderr.trim() || `git diff exit ${diffRes.exitCode}`, |
| 180 | ); |
| 181 | } |
| 182 | } else { |
| 183 | diffRes = await runCommand( |
| 184 | 'git', |
| 185 | ['diff', '--no-color', 'HEAD', '--', rel], |
| 186 | realCwd, |
| 187 | ); |
| 188 | if (diffRes.exitCode !== 0) { |
| 189 | throw new FsGitUnavailableError( |
| 190 | realCwd, |
| 191 | diffRes.stderr.trim() || `git diff exit ${diffRes.exitCode}`, |
nothing calls this directly
no test coverage detected