Docs
Search docs

List a path's commit history

GET/api/repos/{owner}/{repo}/path-history

listRepositoryPathHistory

Returns one page of the first-parent commits that changed a file or directory (`git log --first-parent -- <path>`), newest first, each with what it did to the path. Continue with `cursor = next_cursor`. The history stops at the path's creation (or where it cannot be found): `earlier` then carries the cursor and reason for an explicit `earlier=true` search of older history, which may take several (bounded, possibly empty) pages. `status: pending` means the starting commit is still being indexed; ask again shortly. Mode-only changes (a chmod, or a symlink replaced by a file with the same bytes) are not listed, unlike `git log`; renames are not followed.

Authentication is not described for this operation in the spec — that does not mean it is public. Check tokens and scopes.

curl

curl -X GET 'https://neosource.dev/api/repos/OWNER/REPO/path-history'

fetch

fetch("https://neosource.dev/api/repos/OWNER/REPO/path-history", {
  method: "GET",
});

Path parameters

ownerrequired

Repository owner or organization slug.

string

reporequired

Repository name.

string

Query parameters

ref

Bookmark name (or 40-hex commit id) to read from. Defaults to the repository default branch.

string

path

Slash-delimited repository path, a file or a directory. Absent or empty for the whole tree.

string

cursor

The previous page's `next_cursor`: the commit to continue from (inclusive). Replaces `ref` as the starting point when present.

string

per_page

Entries per page (max 100, default 30).

integerint32

earlier

Search past where the history stops (a previous page's `earlier`): step over spans where the path did not exist. Costs one lookup per change of the path's deepest surviving prefix, bounded per page; a page in this mode may come back empty with a `next_cursor`, which continues the search (pass `earlier=true` again).

boolean

Responses

200One page of the path's history

application/json

PathHistoryResponse

object

One page of `git log --first-parent -- <path>`, newest first.

earlier
one of
  • PathHistoryEarlier

    object

    Where a path's history stopped before the repository's first commit, and how to search on.

    cursorrequired

    string

    Pass as `cursor`, with `earlier=true`, to search earlier history.

    reasonrequired
    HistoryStopReason
  • null

entriesrequired

array

items

PathHistoryEntryResponse

object

One commit of a path's first-parent history.

changerequired
FileChangeKind
commitrequired
CommitResponse
next_cursor

string | null

Pass as `cursor` for the next page (with the same `earlier`). Absent when the history ended or stopped (see `earlier`), or `status` is `pending`. An `earlier=true` page may hold no entries and still carry a cursor: stepping over a span where the path did not exist is bounded per page.

pathrequired

string

The normalized path, `""` for the whole tree.

refrequired

string

statusrequired

PathHistoryStatus

string

Whether a path-history response carries the history or is still waiting on the derived index it is read from.

"ready""pending"

Standard errors

Bodies documented once for the whole API — see standard errors.

  • 400Bad Request — one of: invalid_input
  • 403Forbidden — one of: forbidden
  • 404Not Found — one of: not_found
  • 423Locked — one of: busy
  • 429Rate limited — retry after the interval in the `Retry-After` header
  • 500Internal server error
  • 503Service temporarily unavailable / at capacity — retry after the `Retry-After` header
  • 504Gateway timeout — the request exceeded the server's handling budget

Schemas

Referenced above. Listed here rather than expanded inline, so the same definition is not repeated at every level.

HistoryStopReason

string

Why a path's history stopped before the root with more history possibly behind it. Older than this point the path did not exist on the first-parent line until some earlier change, and finding that change costs one lookup per change of the path's deepest surviving prefix, so it is searched only on request.

"created_here""not_found_yet"

FileChangeKind

string

What a commit in a path's first-parent history did to that path, relative to its first parent: `git log --first-parent --name-status -- <path>`'s letter, without renames (`A`/`M`/`D`; no rename detection is done). Read off ADR 0132's derived rows, so it shares their semantics: a kind flip (file ↔ directory) is `Modified`, and a mode-only change is invisible.

"added""modified""deleted"

CommitResponse

object

authorrequired

CommitSignatureResponse

object

emailrequired

string

namerequired

string

timestamprequired

integerint64

author_account
one of
  • AuthorRef

    object

    A commit author/committer resolved to a platform account, matched at read time on a **verified** email. `None` when the commit's email is not a verified account (imported history, an unverified address, a bot) — the raw `name`/`email` on the signature is still rendered, as GitHub does.

    account_idrequired

    string

    avatar_url

    string | null

    The account's uploaded avatar on the content origin, minted like `UserResponse::avatar_url`; absent when it has none, so the SPA paints the generated fallback without probing `/avatars/{handle}` first.

    display_namerequired

    string

    emailrequired

    string

    handlerequired

    string

  • null

checks
one of
  • CommitChecksSummary

    object

    Rollup of everything that checked a commit: workflow runs it triggered plus external statuses posted against it. `state` follows [`CommitStatusState::rollup`] — `failure` if anything failed, `pending` while anything is still in flight, `success` only when all green. The counts and `state` are PER RUN: every run on the commit, a re-run's superseded earlier attempts included, so a failed attempt re-run green still counts as failed here. `workflows` is the newest attempt of each workflow and can therefore disagree with them; a row's colours come from `workflows` + `statuses` alone.

    failedrequired

    integerint64

    pendingrequired

    integerint64

    Includes `superseded`.

    staterequired

    CommitStatusState

    string

    State of a single commit status, GitHub-shaped. `Error` is distinct from `Failure` on individual statuses (infrastructure/tooling breakage vs. a real red result) but the combined rollup folds both into `Failure`.

    "pending""success""failure""error"

    statuses
    one of
    • CommitStatusesSummary

      object

      The external commit statuses on one commit, rolled up as a single entry.

      staterequired
      CommitStatusState
      totalrequired

      integerint64

    • null

    succeededrequired

    integerint64

    supersededrequired

    integerint64

    Runs the merge queue superseded and cancelled (ADR 0160): they roll `state` up as `pending` (never green, never red) and are a SUBSET of `pending` (`superseded <= pending`) — the ones that will not resolve on their own.

    totalrequired

    integerint64

    workflowsrequired

    array

    The same runs split by workflow: each workflow's newest run (latest attempt) on this commit, in row order (by path, then id). What a commit row paints one icon per; the counts above stay the roll-up.

    items

    WorkflowCheck

    object

    One workflow's newest run on a commit — one icon of a commit or PR row, beside the workflow's siblings, where a single roll-up would hide which workflow was red (`WorkflowVerdict` in neosource-core). Rows receive these already ordered: by `workflow_path`, then `workflow_id`, an unregistered workflow last — never by state.

    run_idrequired

    string

    The newest run (latest attempt) of this workflow on the commit (UUID).

    run_numberrequired

    integerint64

    skippedrequired

    boolean

    Every job of the run was skipped: `status` is `succeeded`, but no work ran.

    statusrequired
    WorkflowRunStatus
    supersededrequired

    boolean

    The merge queue superseded and cancelled this run (ADR 0160): render neutral, neither red nor in flight.

    workflow_idrequired

    string

    Workflow id (UUID).

    workflow_namerequired

    string

    The workflow's declared `name:` as the run pinned it.

    workflow_path

    string | null

    The workflow file's repo path; `null` when the workflow is no longer registered.

  • null

committerrequired

CommitSignatureResponse

object

emailrequired

string

namerequired

string

timestamprequired

integerint64

committer_account
one of
  • AuthorRef

    object

    A commit author/committer resolved to a platform account, matched at read time on a **verified** email. `None` when the commit's email is not a verified account (imported history, an unverified address, a bot) — the raw `name`/`email` on the signature is still rendered, as GitHub does.

    account_idrequired

    string

    avatar_url

    string | null

    The account's uploaded avatar on the content origin, minted like `UserResponse::avatar_url`; absent when it has none, so the SPA paints the generated fallback without probing `/avatars/{handle}` first.

    display_namerequired

    string

    emailrequired

    string

    handlerequired

    string

  • null

messagerequired

string

oidrequired

string

parentsrequired

array

items

string

pull_request
one of
  • CommitPullRequestRef

    object

    The pull request a commit belongs to, resolved at read time by matching the commit against PR heads (`is_head = true`) and historical revision heads (`is_head = false`). `None` when the commit is not any PR's (current or past) head.

    is_headrequired

    boolean

    `true` if this commit is the PR's current head; `false` if it is only a historical revision head.

    numberrequired

    integerint32

    statusrequired

    PullRequestStatus

    string

    Lifecycle status of a pull request.

    "open""merged""closed"

    titlerequired

    string

  • null

treerequired

string

CommitStatusState

string

State of a single commit status, GitHub-shaped. `Error` is distinct from `Failure` on individual statuses (infrastructure/tooling breakage vs. a real red result) but the combined rollup folds both into `Failure`.

"pending""success""failure""error"

WorkflowRunStatus

string

Lifecycle of a workflow run. Mirrors the GHA-shaped surface that the SPA renders. The serde `snake_case` strings are the wire vocabulary the API emits (pinned by the `enum_wire_consistency` tests).

"pending_approval""queued""quota_blocked""concurrency_blocked""running""cancelling""succeeded""failed""cancelled"