> ## Documentation Index
> Fetch the complete documentation index at: https://differens.ossl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# @ossl-dev/differens-git

> Git integration API reference

# @ossl-dev/differens-git

This package shells out to the `git` binary to collect file pairs and registers Differens as a git diff driver. It returns `GitDiffInput[]` pairs ready for the tier pipeline.

Install:

```bash theme={null}
npm install @ossl-dev/differens-git
```

## Exports

| Export                  | Kind     | Description                                                          |
| ----------------------- | -------- | -------------------------------------------------------------------- |
| `diffWorkingTree`       | function | Working tree vs HEAD → `GitDiffInput[]`                              |
| `diffCommitRange`       | function | `"main..feature"` → `GitDiffInput[]`                                 |
| `diffDirectories`       | function | Two directory trees, file by file                                    |
| `readFilePair`          | function | Two standalone files → one `GitDiffInput`                            |
| `installGitDriver`      | function | Register `diff.differens.command` in local git config                |
| `diffDriverCommand`     | function | Render runtime + args into the shell-quoted command git config wants |
| `generateGitAttributes` | function | `.gitattributes` lines (`*.ts diff=differens`)                       |
| `DRIVER_FLAG`           | const    | `"--git-diff-driver"`, the flag that prefixes the args git appends   |
| `MAX_DIFF_BYTES`        | const    | `2 MiB`. Files above this are read but not tree-parsed               |
| `isGitRepo`             | function | Are we inside a git repository?                                      |
| `resolveRef`            | function | Ref → commit SHA, or `null` if invalid                               |

```ts theme={null}
// GitDiffInput:
// { oldPath: string; newPath: string; oldSource: string; newSource: string }
```

## How the diff driver works

Git invokes a registered driver with seven arguments: `path old-file old-hex old-mode new-file new-hex new-mode`. The two file arguments are temporaries that git wrote the blobs to, and they get generated names without extensions. The tier must be picked from `path`. Classifying by temp name would find no extension and line-diff everything.

Both files are handled in one process. The CLI sees `DRIVER_FLAG` and reads the blobs through a single `git cat-file --batch` stream, instead of spawning one `git show` per file per side.

## Usage

<CodeGroup>
  ```ts Diff the working tree theme={null}
  import { diffWorkingTree } from "@ossl-dev/differens-git";

  const pairs = await diffWorkingTree();  // vs HEAD
  for (const p of pairs) {
    console.log(p.oldPath, p.oldSource.length, "->", p.newSource.length);
  }
  ```

  ```ts Diff a commit range theme={null}
  import { diffCommitRange } from "@ossl-dev/differens-git";

  const pairs = await diffCommitRange("main..feature");
  ```

  ```ts Register the diff driver theme={null}
  import { diffDriverCommand, installGitDriver, generateGitAttributes } from "@ossl-dev/differens-git";

  await installGitDriver(diffDriverCommand(process.execPath, ["cli.js", DRIVER_FLAG]));
  console.log(generateGitAttributes(["ts", "tsx", "py", "rs", "go"]));
  // *.ts diff=differens
  // *.tsx diff=differens
  ```
</CodeGroup>

## Removing the driver

There is no uninstall helper yet. Remove the config manually:

```bash theme={null}
git config --unset-all diff.differens.command
git config --unset-all diff.differens.textconv
git config --unset-all diff.differens.cachetextconv
```
