surshar / claude-code
Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.
Built by Anthropic · github.com/anthropics
| 1 | import type Types from '../types' |
| 2 | import { RENAME_RECORDS } from './rename-records' |
| 3 | |
| 4 | /** |
| 5 | * `git diff --numstat -z` output as totals over every row and the first |
| 6 | * rows up to the cap; a binary file (`-` counts) is a 0/0 row marked binary. |
| 7 | * |
| 8 | * A record is `<added>\t<removed>\t<path>` ended by NUL, the path raw; a |
| 9 | * rename is `<added>\t<removed>\t` then the old and the new path as the |
| 10 | * next two records, kept as one row under the new path. |
| 11 | * |
| 12 | * @param stdout the command's standard output |
| 13 | * @param maxFiles how many rows to keep |
| 14 | * @returns the totals and the kept rows |
| 15 | */ |
| 16 | export function parseNumstat( |
| 17 | stdout: string, |
| 18 | maxFiles: number, |
| 19 | ): Types.NumstatResult { |
| 20 | const files: Types.FileStat[] = [] |
| 21 | const stats = { filesCount: 0, linesAdded: 0, linesRemoved: 0 } |
| 22 | const records = stdout.split('\0') |
| 23 | let at = 0 |
| 24 | |
| 25 | while (at < records.length) { |
| 26 | const [addedField, removedField, ...pathFields] = (records[at] ?? '').split( |
| 27 | '\t', |
| 28 | ) |
| 29 | const inline = pathFields.join('\t') |
| 30 | const isRename = pathFields.length === 1 && inline === '' |
| 31 | const renamedFrom = isRename ? (records[at + 1] ?? null) : null |
| 32 | const path = isRename ? (records[at + 2] ?? '') : inline |
| 33 | at += isRename ? RENAME_RECORDS : 1 |
| 34 | const isRow = |
| 35 | addedField !== undefined && removedField !== undefined && path !== '' |
| 36 | |
| 37 | if (!isRow) { |
| 38 | continue |
| 39 | } |
| 40 | |
| 41 | const isBinary = addedField === '-' || removedField === '-' |
| 42 | const added = isBinary ? 0 : Number(addedField) || 0 |
| 43 | const removed = isBinary ? 0 : Number(removedField) || 0 |
| 44 | stats.filesCount += 1 |
| 45 | stats.linesAdded += added |
| 46 | stats.linesRemoved += removed |
| 47 | |
| 48 | if (files.length < maxFiles) { |
| 49 | files.push({ |
| 50 | path, |
| 51 | renamedFrom, |
| 52 | added, |
| 53 | removed, |
| 54 | isBinary, |
| 55 | isUntracked: false, |
| 56 | isPreSession: false, |
| 57 | }) |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | return { stats, files } |
| 62 | } |