4 files changed,
54 insertions(+),
12 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2026-02-24 23:27:33 +0200
Authored at:
2026-02-24 22:56:50 +0200
Change ID:
squqrynrrltxkpllnkmyksqmrlplnwpw
Parent:
b883855
M
internal/git/repo.go
路路路 11 11 "github.com/go-git/go-git/v5" 12 12 "github.com/go-git/go-git/v5/plumbing" 13 13 "github.com/go-git/go-git/v5/plumbing/object" 14 + "github.com/go-git/go-git/v5/plumbing/storer" 14 15 "github.com/go-git/go-git/v5/plumbing/transport" 15 16 "github.com/go-git/go-git/v5/plumbing/transport/http" 16 17 ) 路路路 129 130 } 130 131 } 131 132 132 -func (g *Repo) Commits() ([]*Commit, error) { 133 +const CommitsPage = 150 134 + 135 +// Commits returns [CommitsPage] commits after the given commit hash cursor. 136 +// If after is empty, starts from HEAD. 137 +func (g *Repo) Commits(after string) ([]*Commit, error) { 133 138 if g.IsEmpty() { 134 139 return []*Commit{}, nil 135 140 } 136 141 142 + from := g.h 143 + if after != "" { 144 + hash, err := g.r.ResolveRevision(plumbing.Revision(after)) 145 + if err != nil { 146 + return nil, fmt.Errorf("invalid cursor: %w", err) 147 + } 148 + from = *hash 149 + } 150 + 137 151 ci, err := g.r.Log(&git.LogOptions{ 138 - From: g.h, 152 + From: from, 139 153 Order: git.LogOrderCommitterTime, 140 154 }) 141 155 if err != nil { 142 156 return nil, fmt.Errorf("commits from ref: %w", err) 143 157 } 144 158 145 - var commits []*Commit 159 + // since after commit was shown on prev page, skip it 160 + if after != "" { 161 + ci.Next() 162 + } 163 + 164 + commits := make([]*Commit, 0, CommitsPage) 146 165 ci.ForEach(func(c *object.Commit) error { 166 + if len(commits) == CommitsPage { 167 + return storer.ErrStop 168 + } 147 169 commits = append(commits, newCommit(c)) 148 170 return nil 149 171 })
M
internal/handlers/repo.go
路路路 94 94 return 95 95 } 96 96 97 - p.Commits, err = repo.Commits() 97 + p.Commits, err = repo.Commits("") 98 98 if err != nil { 99 99 h.write500(w, err) 100 100 return 路路路 239 239 } 240 240 241 241 type RepoLog struct { 242 - Desc string 243 - Commits []*git.Commit 244 - Ref string 242 + Desc string 243 + Commits []*git.Commit 244 + Ref string 245 + NextAfter string 245 246 } 246 247 247 248 func (h *handlers) logHandler(w http.ResponseWriter, r *http.Request) { 248 249 name := r.PathValue("name") 249 250 ref := h.parseRef(r.PathValue("ref")) 251 + after := r.URL.Query().Get("after") 250 252 251 253 repo, err := h.openPublicRepo(name, ref) 252 254 if err != nil { 路路路 254 256 return 255 257 } 256 258 257 - commits, err := repo.Commits() 259 + desc, err := repo.Description() 258 260 if err != nil { 259 261 h.write500(w, err) 260 262 return 261 263 } 262 264 263 - desc, err := repo.Description() 265 + commits, err := repo.Commits(after) 264 266 if err != nil { 265 267 h.write500(w, err) 266 268 return 267 269 } 268 270 271 + // if we got full page of commits, we probably have more. 272 + // NOTE: this has edge case, when last page has git.CommitsPage, "load more would be shown" 273 + nextAfter := "" 274 + if len(commits) == git.CommitsPage && len(commits) > 0 { 275 + nextAfter = commits[len(commits)-1].HashShort 276 + } 277 + 269 278 h.templ(w, "repo_log", h.pageData(repo, RepoLog{ 270 - Desc: desc, 271 - Commits: commits, 272 - Ref: ref, 279 + Desc: desc, 280 + Ref: ref, 281 + Commits: commits, 282 + NextAfter: nextAfter, 273 283 })) 274 284 } 275 285