From 1706277d690b04077e5ff7fb6f5c12c88359de23 Mon Sep 17 00:00:00 2001 From: Vasilii Iakliushin Date: Fri, 12 Dec 2025 16:55:04 +0100 Subject: [PATCH 1/2] WIP: optimize Revlist pagination --- internal/git/gitpipe/revision.go | 15 +++++++++++++++ internal/gitaly/service/commit/list_commits.go | 9 ++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/internal/git/gitpipe/revision.go b/internal/git/gitpipe/revision.go index 2070130eb8..93a282dd1a 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 cfb9990a28..c9f9dabaef 100644 --- a/internal/gitaly/service/commit/list_commits.go +++ b/internal/gitaly/service/commit/list_commits.go @@ -120,6 +120,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(limit)) + } + revlistIter := gitpipe.Revlist(ctx, repo, request.GetRevisions(), revlistOptions...) catfileObjectIter, err := gitpipe.CatfileObject(ctx, objectReader, revlistIter) @@ -148,7 +156,6 @@ func (s *server) ListCommits( }, }) - limit := request.GetPaginationParams().GetLimit() parser := catfile.NewParser() for i := int32(0); catfileObjectIter.Next(); i++ { -- GitLab From 8aa2bd15f1d2fc31793755b3a4023dc1d31f3ff2 Mon Sep 17 00:00:00 2001 From: Vasilii Iakliushin Date: Fri, 12 Dec 2025 17:00:57 +0100 Subject: [PATCH 2/2] Fix --- internal/gitaly/service/commit/list_commits.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/gitaly/service/commit/list_commits.go b/internal/gitaly/service/commit/list_commits.go index c9f9dabaef..6e01e3da67 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 { @@ -125,7 +127,7 @@ func (s *server) ListCommits( // 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(limit)) + revlistOptions = append(revlistOptions, gitpipe.WithMaxCount(uint(limit))) } revlistIter := gitpipe.Revlist(ctx, repo, request.GetRevisions(), revlistOptions...) -- GitLab