From e71e384253197b6a9b02c322b345ed9145752470 Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Thu, 14 May 2026 16:56:23 +0530 Subject: [PATCH 1/4] Improve GitHub branch listing pagination --- src/VCS/Adapter.php | 7 ++- src/VCS/Adapter/Git/GitHub.php | 96 ++++++++++++++++++++++++++++---- src/VCS/Adapter/Git/GitLab.php | 2 +- src/VCS/Adapter/Git/Gitea.php | 2 +- src/VCS/Adapter/Git/Gogs.php | 2 +- tests/VCS/Adapter/GitHubTest.php | 58 +++++++++++++++---- 6 files changed, 142 insertions(+), 25 deletions(-) diff --git a/src/VCS/Adapter.php b/src/VCS/Adapter.php index ab8c48cf..6acb4d64 100644 --- a/src/VCS/Adapter.php +++ b/src/VCS/Adapter.php @@ -225,9 +225,12 @@ abstract public function getRepositoryName(string $repositoryId): string; * * @param string $owner Owner name of the repository * @param string $repositoryName Name of the repository - * @return array List of branch names as array + * @param int $perPage Number of branches to fetch per page + * @param int|string|null $page Page number or cursor to start fetching from + * @param string $search Branch name search query + * @return array|array{items: array, hasNext: bool, nextCursor?: string|null} List of branch names or branch names with pagination metadata */ - abstract public function listBranches(string $owner, string $repositoryName): array; + abstract public function listBranches(string $owner, string $repositoryName, int $perPage = 100, int|string|null $page = 1, string $search = ''): array; /** * Updates status check of each commit diff --git a/src/VCS/Adapter/Git/GitHub.php b/src/VCS/Adapter/Git/GitHub.php index d9b45f6c..032158d5 100644 --- a/src/VCS/Adapter/Git/GitHub.php +++ b/src/VCS/Adapter/Git/GitHub.php @@ -747,27 +747,103 @@ public function getPullRequestFromBranch(string $owner, string $repositoryName, * @param string $owner Owner name of the repository * @param string $repositoryName Name of the GitHub repository * @param int $perPage Number of branches to fetch per page - * @param int $page Page number to start fetching from - * @return array List of branch names as array + * @param int|string|null $page Page number or GraphQL cursor to start fetching from + * @param string $search Branch name search query + * @return array{items: array, hasNext: bool, nextCursor: string|null} List of branch names and pagination metadata */ - public function listBranches(string $owner, string $repositoryName, int $perPage = 100, int $page = 1): array + public function listBranches(string $owner, string $repositoryName, int $perPage = 100, int|string|null $page = 1, string $search = ''): array { - $url = "/repos/$owner/$repositoryName/branches"; $perPage = min(max($perPage, 1), 100); + $cursor = is_string($page) ? $page : null; + $page = is_int($page) ? max($page, 1) : 1; + $result = [ + 'items' => [], + 'hasNext' => false, + 'nextCursor' => null, + ]; + + for ($currentPage = 1; $currentPage <= $page; $currentPage++) { + $result = $this->listBranchesPage($owner, $repositoryName, $perPage, $cursor, $search); + + if ($currentPage === $page) { + return $result; + } + + if ($result['hasNext'] === false) { + return [ + 'items' => [], + 'hasNext' => false, + 'nextCursor' => null, + ]; + } + + $cursor = $result['nextCursor']; + } - $response = $this->call(self::METHOD_GET, $url, ['Authorization' => "Bearer $this->accessToken"], [ - 'page' => $page, - 'per_page' => $perPage, + return $result; + } + + /** + * @return array{items: array, hasNext: bool, nextCursor: string|null} + */ + private function listBranchesPage(string $owner, string $repositoryName, int $perPage, ?string $cursor, string $search): array + { + $query = <<<'GRAPHQL' +query ListBranches($owner: String!, $name: String!, $first: Int!, $after: String, $query: String) { + repository(owner: $owner, name: $name) { + refs(refPrefix: "refs/heads/", first: $first, after: $after, query: $query, orderBy: {field: ALPHABETICAL, direction: ASC}) { + nodes { + name + } + pageInfo { + hasNextPage + endCursor + } + } + } +} +GRAPHQL; + + $response = $this->call(self::METHOD_POST, '/graphql', ['Authorization' => "Bearer $this->accessToken"], [ + 'query' => $query, + 'variables' => [ + 'owner' => $owner, + 'name' => $repositoryName, + 'first' => $perPage, + 'after' => $cursor, + 'query' => $search === '' ? null : $search, + ], ]); $statusCode = $response['headers']['status-code'] ?? 0; $responseBody = $response['body'] ?? []; - if ($statusCode < 200 || $statusCode >= 300 || !is_array($responseBody)) { - return []; + if ($statusCode < 200 || $statusCode >= 300 || !is_array($responseBody) || array_key_exists('errors', $responseBody)) { + return [ + 'items' => [], + 'hasNext' => false, + 'nextCursor' => null, + ]; + } + + $refs = $responseBody['data']['repository']['refs'] ?? null; + + if (!is_array($refs)) { + return [ + 'items' => [], + 'hasNext' => false, + 'nextCursor' => null, + ]; } - return array_values(array_map(fn ($branch) => $branch['name'] ?? '', $responseBody)); + $pageInfo = $refs['pageInfo'] ?? []; + $hasNext = $pageInfo['hasNextPage'] ?? false; + + return [ + 'items' => array_values(array_map(fn ($branch) => $branch['name'] ?? '', $refs['nodes'] ?? [])), + 'hasNext' => $hasNext, + 'nextCursor' => $hasNext ? ($pageInfo['endCursor'] ?? null) : null, + ]; } /** diff --git a/src/VCS/Adapter/Git/GitLab.php b/src/VCS/Adapter/Git/GitLab.php index 988cd3e7..2e6eecb8 100644 --- a/src/VCS/Adapter/Git/GitLab.php +++ b/src/VCS/Adapter/Git/GitLab.php @@ -524,7 +524,7 @@ public function getPullRequestFromBranch(string $owner, string $repositoryName, throw new Exception("Not implemented"); } - public function listBranches(string $owner, string $repositoryName): array + public function listBranches(string $owner, string $repositoryName, int $perPage = 100, int|string|null $page = 1, string $search = ''): array { $ownerPath = $this->getOwnerPath($owner); $projectPath = urlencode("{$ownerPath}/{$repositoryName}"); diff --git a/src/VCS/Adapter/Git/Gitea.php b/src/VCS/Adapter/Git/Gitea.php index bc6544ef..449a386a 100644 --- a/src/VCS/Adapter/Git/Gitea.php +++ b/src/VCS/Adapter/Git/Gitea.php @@ -715,7 +715,7 @@ public function getPullRequestFromBranch(string $owner, string $repositoryName, * @param string $repositoryName Name of the repository * @return array Array of branch names */ - public function listBranches(string $owner, string $repositoryName): array + public function listBranches(string $owner, string $repositoryName, int $perPage = 100, int|string|null $page = 1, string $search = ''): array { $allBranches = []; $perPage = 50; diff --git a/src/VCS/Adapter/Git/Gogs.php b/src/VCS/Adapter/Git/Gogs.php index 4a060ece..fa0cf426 100644 --- a/src/VCS/Adapter/Git/Gogs.php +++ b/src/VCS/Adapter/Git/Gogs.php @@ -490,7 +490,7 @@ public function getCommitStatuses(string $owner, string $repositoryName, string * * @return array */ - public function listBranches(string $owner, string $repositoryName): array + public function listBranches(string $owner, string $repositoryName, int $perPage = 100, int|string|null $page = 1, string $search = ''): array { $url = "/repos/{$owner}/{$repositoryName}/branches"; diff --git a/tests/VCS/Adapter/GitHubTest.php b/tests/VCS/Adapter/GitHubTest.php index f87ff182..a65e2a3e 100644 --- a/tests/VCS/Adapter/GitHubTest.php +++ b/tests/VCS/Adapter/GitHubTest.php @@ -471,11 +471,17 @@ public function testListBranches(): void try { $this->vcsAdapter->createFile(static::$owner, $repositoryName, 'README.md', '# Test'); - $branches = $this->vcsAdapter->listBranches(static::$owner, $repositoryName); + /** @var GitHub $adapter */ + $adapter = $this->vcsAdapter; + $branches = $adapter->listBranches(static::$owner, $repositoryName); $this->assertIsArray($branches); - $this->assertNotEmpty($branches); - $this->assertContains(static::$defaultBranch, $branches); + $this->assertArrayHasKey('items', $branches); + $this->assertArrayHasKey('hasNext', $branches); + $this->assertNotEmpty($branches['items']); + $this->assertFalse($branches['hasNext']); + $this->assertNull($branches['nextCursor']); + $this->assertContains(static::$defaultBranch, $branches['items']); } finally { $this->vcsAdapter->deleteRepository(static::$owner, $repositoryName); } @@ -539,13 +545,37 @@ public function testListBranchesPagination(): void $adapter = $this->vcsAdapter; $page1 = $adapter->listBranches(static::$owner, $repositoryName, 1, 1); - $this->assertSame(['branch-a'], $page1); + $this->assertSame(['branch-a'], $page1['items']); + $this->assertTrue($page1['hasNext']); + $this->assertNotEmpty($page1['nextCursor']); $page2 = $adapter->listBranches(static::$owner, $repositoryName, 1, 2); - $this->assertSame(['branch-b'], $page2); + $this->assertSame(['branch-b'], $page2['items']); + $this->assertTrue($page2['hasNext']); + $this->assertNotEmpty($page2['nextCursor']); + + $cursorPage2 = $adapter->listBranches(static::$owner, $repositoryName, 1, $page1['nextCursor']); + $this->assertSame($page2, $cursorPage2); + + $page3 = $adapter->listBranches(static::$owner, $repositoryName, 1, 3); + $this->assertSame([static::$defaultBranch], $page3['items']); + $this->assertFalse($page3['hasNext']); + $this->assertNull($page3['nextCursor']); $all = $adapter->listBranches(static::$owner, $repositoryName, 100, 1); - $this->assertEqualsCanonicalizing([static::$defaultBranch, 'branch-a', 'branch-b'], $all); + $this->assertEqualsCanonicalizing([static::$defaultBranch, 'branch-a', 'branch-b'], $all['items']); + $this->assertFalse($all['hasNext']); + $this->assertNull($all['nextCursor']); + + $searchPage1 = $adapter->listBranches(static::$owner, $repositoryName, 1, 1, 'branch'); + $this->assertSame(['branch-a'], $searchPage1['items']); + $this->assertTrue($searchPage1['hasNext']); + $this->assertNotEmpty($searchPage1['nextCursor']); + + $searchPage2 = $adapter->listBranches(static::$owner, $repositoryName, 1, $searchPage1['nextCursor'], 'branch'); + $this->assertSame(['branch-b'], $searchPage2['items']); + $this->assertFalse($searchPage2['hasNext']); + $this->assertNull($searchPage2['nextCursor']); } finally { $this->vcsAdapter->deleteRepository(static::$owner, $repositoryName); } @@ -557,10 +587,14 @@ public function testListBranchesEmptyRepository(): void $this->vcsAdapter->createRepository(static::$owner, $repositoryName, false); try { - $branches = $this->vcsAdapter->listBranches(static::$owner, $repositoryName); + /** @var GitHub $adapter */ + $adapter = $this->vcsAdapter; + $branches = $adapter->listBranches(static::$owner, $repositoryName); $this->assertIsArray($branches); - $this->assertEmpty($branches); + $this->assertSame([], $branches['items']); + $this->assertFalse($branches['hasNext']); + $this->assertNull($branches['nextCursor']); } finally { $this->vcsAdapter->deleteRepository(static::$owner, $repositoryName); } @@ -568,10 +602,14 @@ public function testListBranchesEmptyRepository(): void public function testListBranchesNonExistingRepository(): void { - $branches = $this->vcsAdapter->listBranches(static::$owner, 'non-existing-repo-' . \uniqid()); + /** @var GitHub $adapter */ + $adapter = $this->vcsAdapter; + $branches = $adapter->listBranches(static::$owner, 'non-existing-repo-' . \uniqid()); $this->assertIsArray($branches); - $this->assertEmpty($branches); + $this->assertSame([], $branches['items']); + $this->assertFalse($branches['hasNext']); + $this->assertNull($branches['nextCursor']); } public function testGetLatestCommit(): void From 6c633f32c0d9f9d12f1f0a806254ac4af77c89dd Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Thu, 14 May 2026 17:03:42 +0530 Subject: [PATCH 2/4] Use prefix search for GitHub branches --- src/VCS/Adapter.php | 2 +- src/VCS/Adapter/Git/GitHub.php | 9 +++++---- tests/VCS/Adapter/GitHubTest.php | 5 +++++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/VCS/Adapter.php b/src/VCS/Adapter.php index 6acb4d64..1c542f90 100644 --- a/src/VCS/Adapter.php +++ b/src/VCS/Adapter.php @@ -227,7 +227,7 @@ abstract public function getRepositoryName(string $repositoryId): string; * @param string $repositoryName Name of the repository * @param int $perPage Number of branches to fetch per page * @param int|string|null $page Page number or cursor to start fetching from - * @param string $search Branch name search query + * @param string $search Branch name prefix search query * @return array|array{items: array, hasNext: bool, nextCursor?: string|null} List of branch names or branch names with pagination metadata */ abstract public function listBranches(string $owner, string $repositoryName, int $perPage = 100, int|string|null $page = 1, string $search = ''): array; diff --git a/src/VCS/Adapter/Git/GitHub.php b/src/VCS/Adapter/Git/GitHub.php index 032158d5..611d6f98 100644 --- a/src/VCS/Adapter/Git/GitHub.php +++ b/src/VCS/Adapter/Git/GitHub.php @@ -748,7 +748,7 @@ public function getPullRequestFromBranch(string $owner, string $repositoryName, * @param string $repositoryName Name of the GitHub repository * @param int $perPage Number of branches to fetch per page * @param int|string|null $page Page number or GraphQL cursor to start fetching from - * @param string $search Branch name search query + * @param string $search Branch name prefix search query * @return array{items: array, hasNext: bool, nextCursor: string|null} List of branch names and pagination metadata */ public function listBranches(string $owner, string $repositoryName, int $perPage = 100, int|string|null $page = 1, string $search = ''): array @@ -788,10 +788,11 @@ public function listBranches(string $owner, string $repositoryName, int $perPage */ private function listBranchesPage(string $owner, string $repositoryName, int $perPage, ?string $cursor, string $search): array { + $refPrefix = 'refs/heads/' . $search; $query = <<<'GRAPHQL' -query ListBranches($owner: String!, $name: String!, $first: Int!, $after: String, $query: String) { +query ListBranches($owner: String!, $name: String!, $refPrefix: String!, $first: Int!, $after: String) { repository(owner: $owner, name: $name) { - refs(refPrefix: "refs/heads/", first: $first, after: $after, query: $query, orderBy: {field: ALPHABETICAL, direction: ASC}) { + refs(refPrefix: $refPrefix, first: $first, after: $after, orderBy: {field: ALPHABETICAL, direction: ASC}) { nodes { name } @@ -809,9 +810,9 @@ private function listBranchesPage(string $owner, string $repositoryName, int $pe 'variables' => [ 'owner' => $owner, 'name' => $repositoryName, + 'refPrefix' => $refPrefix, 'first' => $perPage, 'after' => $cursor, - 'query' => $search === '' ? null : $search, ], ]); diff --git a/tests/VCS/Adapter/GitHubTest.php b/tests/VCS/Adapter/GitHubTest.php index a65e2a3e..90633566 100644 --- a/tests/VCS/Adapter/GitHubTest.php +++ b/tests/VCS/Adapter/GitHubTest.php @@ -576,6 +576,11 @@ public function testListBranchesPagination(): void $this->assertSame(['branch-b'], $searchPage2['items']); $this->assertFalse($searchPage2['hasNext']); $this->assertNull($searchPage2['nextCursor']); + + $substringSearch = $adapter->listBranches(static::$owner, $repositoryName, 100, 1, 'ranch'); + $this->assertSame([], $substringSearch['items']); + $this->assertFalse($substringSearch['hasNext']); + $this->assertNull($substringSearch['nextCursor']); } finally { $this->vcsAdapter->deleteRepository(static::$owner, $repositoryName); } From a13602d48a9fbb57ee98abe2ee14edb457380c2a Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Thu, 14 May 2026 17:10:38 +0530 Subject: [PATCH 3/4] Honor branch pagination in other adapters --- src/VCS/Adapter/Git/GitLab.php | 14 ++++++++++---- src/VCS/Adapter/Git/Gitea.php | 14 ++++++++++---- src/VCS/Adapter/Git/Gogs.php | 8 +++++++- tests/VCS/Adapter/GitLabTest.php | 11 +++++++++++ tests/VCS/Adapter/GiteaTest.php | 11 +++++++++++ 5 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/VCS/Adapter/Git/GitLab.php b/src/VCS/Adapter/Git/GitLab.php index 2e6eecb8..518130eb 100644 --- a/src/VCS/Adapter/Git/GitLab.php +++ b/src/VCS/Adapter/Git/GitLab.php @@ -528,11 +528,13 @@ public function listBranches(string $owner, string $repositoryName, int $perPage { $ownerPath = $this->getOwnerPath($owner); $projectPath = urlencode("{$ownerPath}/{$repositoryName}"); + $perPage = min(max($perPage, 1), 100); + $requestedPage = is_int($page) ? max($page, 1) : 1; $branches = []; - $page = 1; + $currentPage = 1; do { - $pagedUrl = "/projects/{$projectPath}/repository/branches?per_page=100&page={$page}"; + $pagedUrl = "/projects/{$projectPath}/repository/branches?per_page=100&page={$currentPage}"; $response = $this->call(self::METHOD_GET, $pagedUrl, ['PRIVATE-TOKEN' => $this->accessToken]); $responseHeaders = $response['headers'] ?? []; $responseHeadersStatusCode = $responseHeaders['status-code'] ?? 0; @@ -546,10 +548,14 @@ public function listBranches(string $owner, string $repositoryName, int $perPage foreach ($responseBody as $branch) { $branches[] = $branch['name'] ?? ''; } - $page++; + $currentPage++; } while (count($responseBody) === 100); - return $branches; + if ($search !== '') { + $branches = array_values(array_filter($branches, fn ($branch) => str_starts_with($branch, $search))); + } + + return array_slice($branches, ($requestedPage - 1) * $perPage, $perPage); } public function getCommit(string $owner, string $repositoryName, string $commitHash): array diff --git a/src/VCS/Adapter/Git/Gitea.php b/src/VCS/Adapter/Git/Gitea.php index 449a386a..31c9688f 100644 --- a/src/VCS/Adapter/Git/Gitea.php +++ b/src/VCS/Adapter/Git/Gitea.php @@ -718,11 +718,13 @@ public function getPullRequestFromBranch(string $owner, string $repositoryName, public function listBranches(string $owner, string $repositoryName, int $perPage = 100, int|string|null $page = 1, string $search = ''): array { $allBranches = []; - $perPage = 50; + $requestedPerPage = min(max($perPage, 1), 100); + $requestedPage = is_int($page) ? max($page, 1) : 1; + $apiPerPage = 50; $maxPages = 100; for ($currentPage = 1; $currentPage <= $maxPages; $currentPage++) { - $url = "/repos/{$owner}/{$repositoryName}/branches?page={$currentPage}&limit={$perPage}"; + $url = "/repos/{$owner}/{$repositoryName}/branches?page={$currentPage}&limit={$apiPerPage}"; $response = $this->call(self::METHOD_GET, $url, ['Authorization' => "token $this->accessToken"]); @@ -754,12 +756,16 @@ public function listBranches(string $owner, string $repositoryName, int $perPage } } - if ($pageCount < $perPage) { + if ($pageCount < $apiPerPage) { break; } } - return $allBranches; + if ($search !== '') { + $allBranches = array_values(array_filter($allBranches, fn ($branch) => str_starts_with($branch, $search))); + } + + return array_slice($allBranches, ($requestedPage - 1) * $requestedPerPage, $requestedPerPage); } /** diff --git a/src/VCS/Adapter/Git/Gogs.php b/src/VCS/Adapter/Git/Gogs.php index fa0cf426..8d26c2bf 100644 --- a/src/VCS/Adapter/Git/Gogs.php +++ b/src/VCS/Adapter/Git/Gogs.php @@ -492,6 +492,8 @@ public function getCommitStatuses(string $owner, string $repositoryName, string */ public function listBranches(string $owner, string $repositoryName, int $perPage = 100, int|string|null $page = 1, string $search = ''): array { + $perPage = min(max($perPage, 1), 100); + $page = is_int($page) ? max($page, 1) : 1; $url = "/repos/{$owner}/{$repositoryName}/branches"; $response = $this->call(self::METHOD_GET, $url, ['Authorization' => "token $this->accessToken"]); @@ -520,6 +522,10 @@ public function listBranches(string $owner, string $repositoryName, int $perPage } } - return $branches; + if ($search !== '') { + $branches = array_values(array_filter($branches, fn ($branch) => str_starts_with($branch, $search))); + } + + return array_slice($branches, ($page - 1) * $perPage, $perPage); } } diff --git a/tests/VCS/Adapter/GitLabTest.php b/tests/VCS/Adapter/GitLabTest.php index fa4600ff..6b5d4c25 100644 --- a/tests/VCS/Adapter/GitLabTest.php +++ b/tests/VCS/Adapter/GitLabTest.php @@ -870,6 +870,17 @@ public function testListBranches(): void $this->assertContains(static::$defaultBranch, $result); $this->assertContains('feature-branch', $result); $this->assertContains('another-branch', $result); + + $page1 = $this->vcsAdapter->listBranches(static::$owner, $repositoryName, 1, 1); + $page2 = $this->vcsAdapter->listBranches(static::$owner, $repositoryName, 1, 2); + $this->assertSame([$result[0]], $page1); + $this->assertSame([$result[1]], $page2); + + $searchResult = $this->vcsAdapter->listBranches(static::$owner, $repositoryName, 100, 1, 'feature'); + $this->assertSame(['feature-branch'], $searchResult); + + $substringSearch = $this->vcsAdapter->listBranches(static::$owner, $repositoryName, 100, 1, 'eature'); + $this->assertSame([], $substringSearch); } finally { $this->vcsAdapter->deleteRepository(static::$owner, $repositoryName); } diff --git a/tests/VCS/Adapter/GiteaTest.php b/tests/VCS/Adapter/GiteaTest.php index 4fafbf91..42cac81b 100644 --- a/tests/VCS/Adapter/GiteaTest.php +++ b/tests/VCS/Adapter/GiteaTest.php @@ -1438,6 +1438,17 @@ public function testListBranches(): void $this->assertContains('feature-1', $branches); $this->assertContains('feature-2', $branches); $this->assertGreaterThanOrEqual(3, count($branches)); + + $page1 = $this->vcsAdapter->listBranches(static::$owner, $repositoryName, 1, 1); + $page2 = $this->vcsAdapter->listBranches(static::$owner, $repositoryName, 1, 2); + $this->assertSame([$branches[0]], $page1); + $this->assertSame([$branches[1]], $page2); + + $searchResult = $this->vcsAdapter->listBranches(static::$owner, $repositoryName, 100, 1, 'feature'); + $this->assertEqualsCanonicalizing(['feature-1', 'feature-2'], $searchResult); + + $substringSearch = $this->vcsAdapter->listBranches(static::$owner, $repositoryName, 100, 1, 'eature'); + $this->assertSame([], $substringSearch); } finally { $this->vcsAdapter->deleteRepository(static::$owner, $repositoryName); } From abc7f7effc8c7fe2f180dd2231a166ba77fee861 Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Thu, 14 May 2026 17:42:36 +0530 Subject: [PATCH 4/4] Preserve default branch listing behavior --- src/VCS/Adapter/Git/GitLab.php | 4 ++++ src/VCS/Adapter/Git/Gitea.php | 4 ++++ src/VCS/Adapter/Git/Gogs.php | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/VCS/Adapter/Git/GitLab.php b/src/VCS/Adapter/Git/GitLab.php index 518130eb..78223d72 100644 --- a/src/VCS/Adapter/Git/GitLab.php +++ b/src/VCS/Adapter/Git/GitLab.php @@ -555,6 +555,10 @@ public function listBranches(string $owner, string $repositoryName, int $perPage $branches = array_values(array_filter($branches, fn ($branch) => str_starts_with($branch, $search))); } + if ($search === '' && $requestedPage === 1 && $perPage === 100) { + return $branches; + } + return array_slice($branches, ($requestedPage - 1) * $perPage, $perPage); } diff --git a/src/VCS/Adapter/Git/Gitea.php b/src/VCS/Adapter/Git/Gitea.php index 31c9688f..54f9f31a 100644 --- a/src/VCS/Adapter/Git/Gitea.php +++ b/src/VCS/Adapter/Git/Gitea.php @@ -765,6 +765,10 @@ public function listBranches(string $owner, string $repositoryName, int $perPage $allBranches = array_values(array_filter($allBranches, fn ($branch) => str_starts_with($branch, $search))); } + if ($search === '' && $requestedPage === 1 && $requestedPerPage === 100) { + return $allBranches; + } + return array_slice($allBranches, ($requestedPage - 1) * $requestedPerPage, $requestedPerPage); } diff --git a/src/VCS/Adapter/Git/Gogs.php b/src/VCS/Adapter/Git/Gogs.php index 8d26c2bf..2aba1e43 100644 --- a/src/VCS/Adapter/Git/Gogs.php +++ b/src/VCS/Adapter/Git/Gogs.php @@ -526,6 +526,10 @@ public function listBranches(string $owner, string $repositoryName, int $perPage $branches = array_values(array_filter($branches, fn ($branch) => str_starts_with($branch, $search))); } + if ($search === '' && $page === 1 && $perPage === 100) { + return $branches; + } + return array_slice($branches, ($page - 1) * $perPage, $perPage); } }