diff --git a/internal/git/gitpipe/revision.go b/internal/git/gitpipe/revision.go index 2070130eb8c04a147eaa93cfa492bf9d0d34f463..93a282dd1a04350a2f30c9f7157afb42df9334d4 100644 --- a/internal/git/gitpipe/revision.go +++ b/internal/git/gitpipe/revision.go @@ -60,6 +60,7 @@ type revlistConfig struct { skipResult func(*RevisionResult) bool skip uint paths []string + maxCount uint } // RevlistOption is an option for the revlist pipeline step. @@ -206,6 +207,13 @@ func WithPaths(paths ...string) RevlistOption { } } +// WithMaxCount causes git-rev-list(1) to limit the total number of commits. +func WithMaxCount(p uint) RevlistOption { + return func(cfg *revlistConfig) { + cfg.maxCount = p + } +} + // Revlist runs git-rev-list(1) with objects and object names enabled. The returned channel will // contain all object IDs listed by this command. Cancelling the context will cause the pipeline to // be cancelled, too. @@ -312,6 +320,13 @@ func Revlist( ) } + if cfg.maxCount > 0 { + flags = append(flags, gitcmd.Flag{ + Name: fmt.Sprintf("--max-count=%d", cfg.maxCount), + }, + ) + } + var postSepArgs []string if len(cfg.paths) > 0 { postSepArgs = append(postSepArgs, cfg.paths...) diff --git a/internal/gitaly/service/commit/list_commits.go b/internal/gitaly/service/commit/list_commits.go index cfb9990a28e723334fa9d4526e81d1e262725eee..6e01e3da67396d08022a6fdea25592fcb6f1398a 100644 --- a/internal/gitaly/service/commit/list_commits.go +++ b/internal/gitaly/service/commit/list_commits.go @@ -104,9 +104,11 @@ func (s *server) ListCommits( revlistOptions = append(revlistOptions, gitpipe.WithCommitMessagePatterns(request.GetCommitMessagePatterns())) } + token := request.GetPaginationParams().GetPageToken() + // If we've got a pagination token, then we will only start to print commits as soon as // we've seen the token. - if token := request.GetPaginationParams().GetPageToken(); token != "" { + if token != "" { tokenSeen := false revlistOptions = append(revlistOptions, gitpipe.WithSkipRevlistResult(func(r *gitpipe.RevisionResult) bool { if !tokenSeen { @@ -120,6 +122,14 @@ func (s *server) ListCommits( })) } + limit := request.GetPaginationParams().GetLimit() + + // If pagination token is missing but limit is set + // Use --max-count option to limit commit results + if limit > 0 && len(token) == 0 { + revlistOptions = append(revlistOptions, gitpipe.WithMaxCount(uint(limit))) + } + revlistIter := gitpipe.Revlist(ctx, repo, request.GetRevisions(), revlistOptions...) catfileObjectIter, err := gitpipe.CatfileObject(ctx, objectReader, revlistIter) @@ -148,7 +158,6 @@ func (s *server) ListCommits( }, }) - limit := request.GetPaginationParams().GetLimit() parser := catfile.NewParser() for i := int32(0); catfileObjectIter.Next(); i++ {