spacehub

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

claude-code / mods / diff / hooks / git / parse / parse-numstat.ts
65 lines · 1.8 KBRaw
1import type Types from '../types'
2import { 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 */
16export 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
30 const inline = pathFields.join('\t')
31 const isRename = pathFields.length === 1 && inline === ''
32 const renamedFrom = isRename ? (records[at + 1] ?? null) : null
33 const path = isRename ? (records[at + 2] ?? '') : inline
34 at += isRename ? RENAME_RECORDS : 1
35
36 const isRow =
37 addedField !== undefined && removedField !== undefined && path !== ''
38
39 if (!isRow) {
40 continue
41 }
42
43 const isBinary = addedField === '-' || removedField === '-'
44 const added = isBinary ? 0 : Number(addedField) || 0
45 const removed = isBinary ? 0 : Number(removedField) || 0
46
47 stats.filesCount += 1
48 stats.linesAdded += added
49 stats.linesRemoved += removed
50
51 if (files.length < maxFiles) {
52 files.push({
53 path,
54 renamedFrom,
55 added,
56 removed,
57 isBinary,
58 isUntracked: false,
59 isPreSession: false,
60 })
61 }
62 }
63
64 return { stats, files }
65}