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

# repo.getBlame()

> Show what revision and author last modified each line of a file.

> [!WARNING]
>
> This page documents the earlier Code Storage SDKs: `@pierre/storage`, `pierre-storage`, and
> `code-storage-go`. New code uses the [Pierre SDK](https://code.storage/docs/sdks.md). To move code to the new SDK, use the
> [`pierre-migrate`
> skill](https://github.com/pierrecomputer/skills/tree/main/skills/pierre-migrate).

```typescript TypeScript theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
const blame = await repo.getBlame({
  path: 'src/api/auth.ts',
  ref: 'main',
});

console.log(`${blame.path} @ ${blame.commitSha}`);
for (const line of blame.lines) {
  console.log(
    `${line.lineNumber}\t${line.commitSha.slice(0, 8)}\t${line.authorName}\t${line.summary}`,
  );
}

// Range + rename detection
const range = await repo.getBlame({
  path: 'src/api/auth.ts',
  ref: 'main',
  ranges: ['10,40'],
  detectMoves: true,
});
```

```python Python theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
blame = await repo.get_blame(
    path="src/api/auth.py",
    ref="main",
)

print(f"{blame['path']} @ {blame['commit_sha']}")
for line in blame["lines"]:
    print(
        f"{line['line_number']}\t{line['commit_sha'][:8]}\t"
        f"{line['author_name']}\t{line['summary']}"
    )

# Range + rename detection
range_blame = await repo.get_blame(
    path="src/api/auth.py",
    ref="main",
    ranges=["10,40"],
    detect_moves=True,
)
```

```go Go theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
blame, err := repo.GetBlame(context.Background(), storage.BlameOptions{
    Path: "src/api/auth.go",
    Ref:  "main",
})
if err != nil {
    log.Fatal(err)
}

fmt.Printf("%s @ %s\n", blame.Path, blame.CommitSHA)
for _, line := range blame.Lines {
    fmt.Printf("%d\t%s\t%s\t%s\n",
        line.LineNumber, line.CommitSHA[:8], line.AuthorName, line.Summary)
}

// Range + rename detection
rangeBlame, err := repo.GetBlame(context.Background(), storage.BlameOptions{
    Path:        "src/api/auth.go",
    Ref:         "main",
    Ranges:      []string{"10,40"},
    DetectMoves: true,
})
```

## Options

**path** `string` *required*

Path to the file within the repository.

**ref** `string`

Branch name, tag, or commit SHA. Defaults to the default branch.

**ephemeral** `boolean`

When `true`, resolves the ref under the ephemeral namespace.

**ranges** `string[]`

`git blame -L`-style range specs. Each entry is one `-L` argument: numeric
ranges (`"10,20"`), regex anchors (`"/getUser/,/^}/"`), relative offsets
(`"10,+5"`), half-open ranges (`"10,"`, `",20"`), a single line (`"10"`), or
function names (`":funcname"`). Up to 16 specs per request. Omit to blame
the whole file. (TypeScript: `ranges`, Python: `ranges`, Go: `Ranges`.)

**detectMoves** `boolean`

Follow the file across renames and copies (passes `-C -C -M` to `git blame`).

**ttl** `number`

Token TTL in seconds.

## Response

**ref** `string`

The ref the blame ran against. When the request omitted `ref`, this is the repository's default
branch.

**path** `string`

Echo of the requested file path.

**commitSha** `string`

The fully-resolved commit SHA that `ref` pointed to when the blame ran.

**lines** `array`

One entry per blamed line, in file order.

Each entry has:

* `lineNumber` — 1-based line number in the file at `ref`
* `commitSha` — commit that last touched the line
* `originalLineNumber` — line number in the originating commit (differs after edits)
* `originalPath` — path in the originating commit (differs after renames when `detectMoves` is on)
* `previousCommitSha` — parent commit that touched the line; omitted for the initial commit
* `authorName`, `authorEmail`
* `authorTime` (parsed `Date` in TypeScript, `datetime` in Python, `time.Time` in Go)
* `rawAuthorTime` — RFC 3339 string as returned by the server
* `committerName`, `committerEmail`, `committerTime`, `rawCommitterTime`
* `summary` — first line of the commit message

## Notes

* Commit metadata is duplicated per line in the SDK result; if you need a deduped commit map, group
  by `commitSha` client-side.
* Each `ranges` entry is one `git blame -L` argument. Supported forms: a single line `"10"`, a
  numeric range `"10,20"`, an offset `"10,+5"` / `"10,-5"`, a regex `"/getUser/"`, a regex pair
  `"/start/,/end/"`, regex + offset `"/start/,+30"`, half-open ranges `"10,"` and `",20"`, and
  `":funcname"` for function-body targeting. Line numbers are 1-based and inclusive; ranges that
  resolve to lines outside the file return a 400, not a silent clamp. Up to 16 specs per request,
  each capped at 256 characters (regex content capped at 200).
* Annotated tags are peeled to the underlying commit, so `commitSha` always equals the dereferenced
  commit (`git rev-parse <ref>^{}`).
* Symlinks blame as a single line of the link-target text. Binary files (including ones that cross
  git's 8 KiB heuristic via embedded NUL bytes) are blamed as text.
* `path` may not contain NUL bytes.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.