ref:802e450cbe1231dc1a685c44fd51e04cbb9e9ceb

feat: cursor-based pagination for commit log (log_page/log_continue)

Each page is O(page_size) regardless of depth — no re-walking from HEAD. The cursor serializes the walk frontier (queue SHAs) so continuation reconstructs the priority queue exactly where the previous page left off. Works correctly across merge histories where single-SHA cursors fail. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SHA: 802e450cbe1231dc1a685c44fd51e04cbb9e9ceb
Author: Cole Christensen <cole.christensen@macmillan.com>
Date: 2026-02-26 21:57
Parents: 33706a5
3 files changed +163 -0
Type
lib/ex_git_objectstore.ex +21 −0
@@ -156,6 +156,27 @@
end
@doc """
Paginated log returning `{:ok, commits, cursor}`. Pass cursor to
`log_continue/3` for the next page. Each page is O(page_size).
"""
@spec log_page(Repo.t(), sha() | ref_name(), keyword()) ::
{:ok, [{sha(), Commit.t()}], [sha()]} | {:error, term()}
def log_page(%Repo{} = repo, ref_or_sha, opts \\ []) do
with {:ok, sha} <- resolve(repo, ref_or_sha) do
Walk.log_page(repo, sha, opts)
end
end
@doc """
Continue a paginated log from a cursor. Returns `{:ok, [], []}` when done.
"""
@spec log_continue(Repo.t(), [sha()], keyword()) ::
{:ok, [{sha(), Commit.t()}], [sha()]} | {:error, term()}
def log_continue(%Repo{} = repo, cursor, opts \\ []) do
Walk.log_continue(repo, cursor, opts)
end
@doc """
Get a tree listing at a given path for a ref or SHA.
Path "/" returns the root tree.
"""