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 Limits from '../../limits' |
| 2 | import Argv from '../argv' |
| 3 | import { EMPTY_FILE_HUNKS } from '../empty-file-hunks' |
| 4 | import Parse from '../parse' |
| 5 | import type Types from '../types' |
| 6 | import { isLastOfDiff } from './is-last-of-diff' |
| 7 | import { withClosingLine } from './with-closing-line' |
| 8 | |
| 9 | /** |
| 10 | * The rows' hunks against the base their counts were read against, from one |
| 11 | * git child over their literal paths; each but the last, a closing empty row. |
| 12 | * |
| 13 | * A row with no body (untracked, binary, renamed, or staged then edited on |
| 14 | * an unborn HEAD) is never named to git. Paths past MAX_PATHSPEC_CHARS and |
| 15 | * files a cut answer left unread go to a further child. |
| 16 | * |
| 17 | * @param run runs git against the pinned repository |
| 18 | * @param data the fetch the rows belong to |
| 19 | * @param files the rows |
| 20 | * @returns each row's parsed body by path, null where git failed |
| 21 | */ |
| 22 | export async function fetchHunks( |
| 23 | run: Types.GitRun, |
| 24 | data: Types.DiffData, |
| 25 | files: readonly Types.FileStat[], |
| 26 | ): Promise<ReadonlyMap<string, Types.FileHunks | null>> { |
| 27 | const bodied = files.filter( |
| 28 | file => |
| 29 | !file.isUntracked && |
| 30 | !file.isBinary && |
| 31 | file.renamedFrom === null && |
| 32 | !data.stalePaths.includes(file.path), |
| 33 | ) |
| 34 | |
| 35 | const bodiless = files |
| 36 | .filter(file => !bodied.includes(file)) |
| 37 | .map(file => [file.path, EMPTY_FILE_HUNKS] as const) |
| 38 | |
| 39 | if (bodied.length === 0) { |
| 40 | return new Map(bodiless) |
| 41 | } |
| 42 | |
| 43 | let spent = 0 |
| 44 | |
| 45 | const asked = bodied |
| 46 | .map(file => file.path) |
| 47 | .filter((path, at) => { |
| 48 | spent += path.length |
| 49 | |
| 50 | return at === 0 || spent <= Limits.MAX_PATHSPEC_CHARS |
| 51 | }) |
| 52 | |
| 53 | const { exitCode, stdout } = await run([ |
| 54 | '--literal-pathspecs', |
| 55 | ...Argv.DIFF_LEADING_ARGS, |
| 56 | ...Argv.HUNKS_ARGS, |
| 57 | data.baseRef, |
| 58 | '--', |
| 59 | ...asked, |
| 60 | ]) |
| 61 | |
| 62 | const hasAnswered = exitCode === 0 |
| 63 | |
| 64 | const settled = hasAnswered |
| 65 | ? Parse.parseFileDiffs(stdout, asked) |
| 66 | : new Map<string, Types.FileHunks>() |
| 67 | |
| 68 | const waiting = bodied.filter(file => !settled.has(file.path)) |
| 69 | const isStuck = settled.size === 0 |
| 70 | |
| 71 | const rest = isStuck |
| 72 | ? waiting.map(file => [file.path, null] as const) |
| 73 | : await fetchHunks(run, data, waiting) |
| 74 | |
| 75 | return new Map<string, Types.FileHunks | null>([ |
| 76 | ...bodiless, |
| 77 | ...bodied.flatMap(file => { |
| 78 | const body = settled.get(file.path) |
| 79 | const isLast = isLastOfDiff(data, file) |
| 80 | |
| 81 | return body |
| 82 | ? [[file.path, isLast ? body : withClosingLine(body)] as const] |
| 83 | : [] |
| 84 | }), |
| 85 | ...rest, |
| 86 | ]) |
| 87 | } |