| 152 | oldIsSymlink: boolean; |
| 153 | newIsSymlink: boolean; |
| 154 | /** |
| 155 | * A pure rename/copy (100% similarity) emits only `similarity index` + |
| 156 | * `rename from`/`rename to` — no mode or index lines — so the sides' mode |
| 157 | * cannot be read from the patch and must be resolved from git. |
| 158 | */ |
| 159 | modeUnknown: boolean; |
| 160 | } |
| 161 | |
| 162 | function parseFilePathsFromPatch(patch: string): ParsedFilePaths[] { |
| 163 | if (!patch.trim()) return []; |
| 164 | |
| 165 | const segments = patch.split(/\ndiff --git /); |
| 166 | const results: ParsedFilePaths[] = []; |
| 167 | |
| 168 | for (let i = 0; i < segments.length; i++) { |
| 169 | const segment = segments[i]; |
| 170 | if (segment === undefined) continue; |
| 171 | const text = i === 0 ? segment : `diff --git ${segment}`; |
| 172 | if (!text.startsWith("diff --git ")) continue; |