|
9 | 9 | "bytes"
|
10 | 10 | "container/list"
|
11 | 11 | "fmt"
|
| 12 | + "io" |
| 13 | + "io/ioutil" |
12 | 14 | "strconv"
|
13 | 15 | "strings"
|
14 | 16 |
|
@@ -327,8 +329,41 @@ func (repo *Repository) FileCommitsCount(revision, file string) (int64, error) {
|
327 | 329 |
|
328 | 330 | // CommitsByFileAndRange return the commits according revison file and the page
|
329 | 331 | func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) (*list.List, error) {
|
330 |
| - stdout, err := NewCommand("log", revision, "--follow", "--skip="+strconv.Itoa((page-1)*50), |
331 |
| - "--max-count="+strconv.Itoa(CommitsRangeSize), prettyLogFormat, "--", file).RunInDirBytes(repo.Path) |
| 332 | + skip := (page - 1) * CommitsRangeSize |
| 333 | + |
| 334 | + stdoutReader, stdoutWriter := io.Pipe() |
| 335 | + defer func() { |
| 336 | + _ = stdoutReader.Close() |
| 337 | + _ = stdoutWriter.Close() |
| 338 | + }() |
| 339 | + go func() { |
| 340 | + stderr := strings.Builder{} |
| 341 | + err := NewCommand("log", revision, "--follow", |
| 342 | + "--max-count="+strconv.Itoa(CommitsRangeSize*page), |
| 343 | + prettyLogFormat, "--", file). |
| 344 | + RunInDirPipeline(repo.Path, stdoutWriter, &stderr) |
| 345 | + if err != nil { |
| 346 | + if stderr.Len() > 0 { |
| 347 | + err = fmt.Errorf("%v - %s", err, stderr.String()) |
| 348 | + } |
| 349 | + _ = stdoutWriter.CloseWithError(err) |
| 350 | + } else { |
| 351 | + _ = stdoutWriter.Close() |
| 352 | + } |
| 353 | + }() |
| 354 | + |
| 355 | + if skip > 0 { |
| 356 | + _, err := io.CopyN(ioutil.Discard, stdoutReader, int64(skip*41)) |
| 357 | + if err != nil { |
| 358 | + if err == io.EOF { |
| 359 | + return list.New(), nil |
| 360 | + } |
| 361 | + _ = stdoutReader.CloseWithError(err) |
| 362 | + return nil, err |
| 363 | + } |
| 364 | + } |
| 365 | + |
| 366 | + stdout, err := ioutil.ReadAll(stdoutReader) |
332 | 367 | if err != nil {
|
333 | 368 | return nil, err
|
334 | 369 | }
|
|
0 commit comments