| 192 | |
| 193 | |
| 194 | def parse_raw_diff(diff: str) -> List[RawDiffLine]: |
| 195 | # each diff line can be two or three parts. The parts and lines are both null-delimited. |
| 196 | # The "lines" start with ":". |
| 197 | parts = diff.strip('\0').split('\0') |
| 198 | lines = [] |
| 199 | numstats = [] |
| 200 | curline = None |
| 201 | for part in parts: |
| 202 | if part.startswith(':'): |
| 203 | curline = [part] |
| 204 | lines.append(curline) |
| 205 | elif m := re.match(r'(\d+|-)\t(\d+|-)\t', part): |
| 206 | # numstat line |
| 207 | add, drop = m.group(1), m.group(2) |
| 208 | curline = [int(add) if add != '-' else None, int(drop) if drop != '-' else None] |
| 209 | numstats.append(curline) |
| 210 | else: |
| 211 | curline.append(part) |
| 212 | diff_lines = [] |
| 213 | for line, stats in zip(lines, numstats): |
| 214 | diff = parse_raw_diff_line(line) |
| 215 | diff.num_add = stats[0] |
| 216 | diff.num_delete = stats[1] |
| 217 | diff_lines.append(diff) |
| 218 | return diff_lines |