web frontend for git repositories, written in Go git.pocka.jp/legit.git
3

Configure Feed

Select the types of activity you want to include in your feed.

Fix long commit history slowing summary page

https://tangled.org/pocka.jp/legit/issues/7#comment-3mqn5xujwoh22

The summary page displays recent up to three commits, but underlying
logic reads the whole repo history then subslice the result. The loading
of entire commit history is really demanding task and slows the response
time of a summary page down a lot.

Before this patch, loading a summary page of Zig project took 900ms ~
1100ms. After this patch, it's 180ms under load.

Shota FUJI (Jul 15, 2026, 2:09 PM +0900) 6248d4ed 62b73d36

+32 -13
+30 -7
git/git.go
··· 104 104 return &g, nil 105 105 } 106 106 107 - func (g *GitRepo) Commits() ([]*object.Commit, error) { 107 + type CommitsOptions struct { 108 + // Limit is maximum number of commits to retrieve. 109 + // 0 means no limit. 110 + Limit uint32 111 + } 112 + 113 + func (g *GitRepo) Commits(opts CommitsOptions) ([]*object.Commit, error) { 108 114 ci, err := g.r.Log(&git.LogOptions{From: g.h}) 109 115 if err != nil { 110 116 return nil, fmt.Errorf("commits from ref: %w", err) 111 117 } 112 118 113 - commits := []*object.Commit{} 114 - ci.ForEach(func(c *object.Commit) error { 115 - commits = append(commits, c) 116 - return nil 117 - }) 119 + if opts.Limit > 0 { 120 + commits := make([]*object.Commit, 0, opts.Limit) 121 + 122 + for range opts.Limit { 123 + if next, err := ci.Next(); err != nil { 124 + if err != io.EOF { 125 + return nil, fmt.Errorf("log failure: %w", err) 126 + } 127 + } else { 128 + commits = append(commits, next) 129 + } 130 + } 118 131 119 - return commits, nil 132 + return commits, nil 133 + } else { 134 + commits := []*object.Commit{} 135 + 136 + ci.ForEach(func(c *object.Commit) error { 137 + commits = append(commits, c) 138 + return nil 139 + }) 140 + 141 + return commits, nil 142 + } 120 143 } 121 144 122 145 func (g *GitRepo) LastCommit() (*object.Commit, error) {
+2 -6
routes/routes.go
··· 116 116 return 117 117 } 118 118 119 - commits, err := gr.Commits() 119 + commits, err := gr.Commits(git.CommitsOptions{Limit: 3}) 120 120 if err != nil { 121 121 d.Write500(w) 122 122 log.Println(err) ··· 157 157 readmeContent = template.HTML(result) 158 158 break 159 159 } 160 - } 161 - 162 - if len(commits) >= 3 { 163 - commits = commits[:3] 164 160 } 165 161 166 162 data := repoTopData{ ··· 457 453 return 458 454 } 459 455 460 - commits, err := gr.Commits() 456 + commits, err := gr.Commits(git.CommitsOptions{}) 461 457 if err != nil { 462 458 d.Write500(w) 463 459 log.Println(err)