+47
-7
knotserver/git/git.go
+47
-7
knotserver/git/git.go
···
142
142
return &g, nil
143
143
}
144
144
145
-
func (g *GitRepo) Commits() ([]*object.Commit, error) {
146
-
ci, err := g.r.Log(&git.LogOptions{From: g.h})
145
+
func (g *GitRepo) Commits(offset, limit int) ([]*object.Commit, error) {
146
+
commits := []*object.Commit{}
147
+
148
+
output, err := g.revList(
149
+
fmt.Sprintf("--skip=%d", offset),
150
+
fmt.Sprintf("--max-count=%d", limit),
151
+
)
147
152
if err != nil {
148
153
return nil, fmt.Errorf("commits from ref: %w", err)
149
154
}
150
155
151
-
commits := []*object.Commit{}
152
-
ci.ForEach(func(c *object.Commit) error {
153
-
commits = append(commits, c)
154
-
return nil
155
-
})
156
+
lines := strings.Split(strings.TrimSpace(string(output)), "\n")
157
+
if len(lines) == 1 && lines[0] == "" {
158
+
return commits, nil
159
+
}
160
+
161
+
for _, item := range lines {
162
+
obj, err := g.r.CommitObject(plumbing.NewHash(item))
163
+
if err != nil {
164
+
continue
165
+
}
166
+
commits = append(commits, obj)
167
+
}
156
168
157
169
return commits, nil
170
+
}
171
+
172
+
func (g *GitRepo) TotalCommits() (int, error) {
173
+
output, err := g.revList(
174
+
fmt.Sprintf("--count"),
175
+
)
176
+
if err != nil {
177
+
return 0, fmt.Errorf("failed to run rev-list", err)
178
+
}
179
+
180
+
count, err := strconv.Atoi(strings.TrimSpace(string(output)))
181
+
if err != nil {
182
+
return 0, err
183
+
}
184
+
185
+
return count, nil
186
+
}
187
+
188
+
func (g *GitRepo) revList(extraArgs ...string) ([]byte, error) {
189
+
var args []string
190
+
args = append(args, "rev-list")
191
+
args = append(args, g.h.String())
192
+
args = append(args, extraArgs...)
193
+
194
+
cmd := exec.Command("git", args...)
195
+
cmd.Dir = g.path
196
+
197
+
return cmd.Output()
158
198
}
159
199
160
200
func (g *GitRepo) Commit(h plumbing.Hash) (*object.Commit, error) {
+17
-22
knotserver/routes.go
+17
-22
knotserver/routes.go
···
87
87
}
88
88
}
89
89
90
-
commits, err := gr.Commits()
91
-
total := len(commits)
90
+
commits, err := gr.Commits(0, 60) // a good preview of commits in this repo
92
91
if err != nil {
93
92
writeError(w, err.Error(), http.StatusInternalServerError)
94
93
l.Error("fetching commits", "error", err.Error())
95
94
return
96
95
}
97
-
if len(commits) > 10 {
98
-
commits = commits[:10]
96
+
97
+
total, err := gr.TotalCommits()
98
+
if err != nil {
99
+
writeError(w, err.Error(), http.StatusInternalServerError)
100
+
l.Error("fetching commits", "error", err.Error())
101
+
return
99
102
}
100
103
101
104
branches, err := gr.Branches()
···
349
352
return
350
353
}
351
354
352
-
commits, err := gr.Commits()
353
-
if err != nil {
354
-
writeError(w, err.Error(), http.StatusInternalServerError)
355
-
l.Error("fetching commits", "error", err.Error())
356
-
return
357
-
}
358
-
359
355
// Get page parameters
360
356
page := 1
361
357
pageSize := 30
···
372
368
}
373
369
}
374
370
375
-
// Calculate pagination
376
-
start := (page - 1) * pageSize
377
-
end := start + pageSize
378
-
total := len(commits)
371
+
// convert to offset/limit
372
+
offset := (page - 1) * pageSize
373
+
limit := pageSize
379
374
380
-
if start >= total {
381
-
commits = []*object.Commit{}
382
-
} else {
383
-
if end > total {
384
-
end = total
385
-
}
386
-
commits = commits[start:end]
375
+
commits, err := gr.Commits(offset, limit)
376
+
if err != nil {
377
+
writeError(w, err.Error(), http.StatusInternalServerError)
378
+
l.Error("fetching commits", "error", err.Error())
379
+
return
387
380
}
381
+
382
+
total := len(commits)
388
383
389
384
resp := types.RepoLogResponse{
390
385
Commits: commits,