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 / git-backend-of.ts
79 lines · 2.3 KBRaw
1import type Backend from '../backend'
2import Limits from '../limits'
3import Argv from './argv'
4import { FAILED_RUN } from './failed-run'
5import { fetchDiff } from './fetch-diff'
6import { fetchFileHunks } from './fetch-file-hunks'
7import { GIT_BASE_MODES } from './git-base-modes'
8import { GIT_WORDS } from './git-words'
9import Probes from './probes'
10import type Types from './types'
11
12/**
13 * The git backend over the session's directory: the repository read with
14 * one `rev-parse` in that directory, then every child pinned to it.
15 *
16 * Each child runs with `--git-dir`, `--work-tree` and cwd the top, under
17 * the C locale and the fetch's timeout (the built-in's execPinnedGit); the
18 * first fetch reads the paths dirty then, once (Probes.dirtyPathsOf).
19 *
20 * @param host the bound host's runner and probes
21 * @returns the backend, or null outside a git working tree
22 */
23export async function gitBackendOf(
24 host: Backend.BackendHost,
25): Promise<Backend.Backend | null> {
26 const runOf =
27 (pinned: Types.Repository | null): Types.GitRun =>
28 async argv => {
29 try {
30 return await host.run(
31 ['git', ...(pinned ? Argv.pinnedLeadOf(pinned) : []), ...argv],
32 {
33 timeoutMs: Limits.GIT_TIMEOUT_MS,
34 env: Argv.GIT_CHILD_ENV,
35 ...(pinned && { cwd: pinned.toplevel }),
36 },
37 )
38 } catch {
39 return FAILED_RUN
40 }
41 }
42
43 const repository = await Probes.repositoryOf(runOf(null))
44
45 if (!repository) {
46 return null
47 }
48
49 const run = runOf(repository)
50
51 let baseline: Promise<ReadonlySet<string> | null> | null = null
52
53 const depsOf = (dirty: ReadonlySet<string> | null): Types.GitDeps => ({
54 run,
55 repository,
56 mtimeOf: host.mtimeOf,
57 entryKindsOf: host.entryKindsOf,
58 sessionStartMs: host.sessionStartMsOf(),
59 baseline: dirty,
60 onBranchBase: host.onBranchBase,
61 })
62
63 return {
64 repository,
65 baseModes: GIT_BASE_MODES,
66 words: GIT_WORDS,
67 fetchDiff: async mode => {
68 baseline ??= Probes.dirtyPathsOf(run)
69
70 return fetchDiff(depsOf(await baseline), mode)
71 },
72 fetchFileHunks: (data, file) => fetchFileHunks(run, data, file),
73 headKeyOf: () =>
74 Probes.headKeyOf(
75 { ...depsOf(null), readFile: host.readFile },
76 repository,
77 ),
78 }
79}