|
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