<!-- Generated by scripts/gen-docs.ts from the TSDoc in src/. Do not edit by hand. -->

# `git/git`

Source: [`src/git/git.ts`](https://github.com/AI-for-dev/combo/blob/main/src/git/git.ts)

The git a run is allowed to do - and nothing else.

**A prompt is not a permission boundary.** An agent given `bash` and told
"never push" will push the day it decides that is what the user meant. So the
agent writes the commit *message* - a text, which is what a model is for - and
the irreversible act stays here, in code that can only do what it has
functions for.

What has no function here, on purpose: `push`, `reset`, `rebase`, `checkout`
of an existing branch, anything `--force`, anything that rewrites history.
Adding one is a decision someone has to take in a diff, not an argument a
model can produce at runtime.

`deleteBranch` is the one that looks like an exception and is not: `-d` makes
git refuse any branch holding commits nothing else reaches, so it can clear
away a name and never work.

## `branchName`

*function*

```typescript
export function branchName(request: string, prefix = "combo"): string { /* … */ }
```

A branch name from a request: `combo/add-a-cache`.

Kept short and free of anything git dislikes. The prefix says who made it, so
a `git branch` listing shows at a glance what came from a run.

## `commitAll`

*function*

```typescript
export async function commitAll(cwd: string, message: string): Promise<GitResult<string>> { /* … */ }
```

Stages everything and commits it, with the message read from stdin.

`-F -` rather than `-m`: a message written by a model contains quotes,
backticks and newlines, and none of them should ever reach a shell. There is
no shell here at all, and this keeps it that way for the body too.

Returns the short sha. A clean working tree is an error, not an empty commit.

## `createBranch`

*function*

```typescript
export async function createBranch(cwd: string, name: string): Promise<GitResult<string>> { /* … */ }
```

Creates a branch and switches to it.

`checkout -b` fails when the branch exists, and that failure is kept: landing
on somebody else's branch is exactly what a dedicated branch is meant to
prevent.

## `diff`

*function*

```typescript
export async function diff(cwd: string, maxBytes = 60_000): Promise<GitResult<string>> { /* … */ }
```

The diff itself, truncated to `maxBytes`.

It is written straight into a prompt, and an agent that receives half a
megabyte of diff writes a worse message than one that receives the first
pages and is told it was cut.

## `diffStat`

*function*

```typescript
export async function diffStat(cwd: string): Promise<GitResult<string>> { /* … */ }
```

`git diff --stat` over tracked changes, including what is staged.

## `isRepository`

*function*

```typescript
export async function isRepository(cwd: string): Promise<boolean> { /* … */ }
```

Whether `cwd` is inside a git working tree.

## `status`

*function*

```typescript
export async function status(cwd: string): Promise<GitResult<string>> { /* … */ }
```

Porcelain status. Empty means a clean working tree - nothing to commit.

## `untracked`

*function*

```typescript
export async function untracked(cwd: string): Promise<string[]> { /* … */ }
```

Untracked files, which `git diff` does not show but `git add -A` will commit.
