Skip to content

Commit 2ffd771

Browse files
authored
Switch branch quick pick is not showing all branches (#8365)
Fixes #8351
1 parent 73b4671 commit 2ffd771

File tree

6 files changed

+57
-12
lines changed

6 files changed

+57
-12
lines changed

src/common/async.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ export function throttle<T>(fn: () => Promise<T>): () => Promise<T> {
3636
return trigger;
3737
}
3838

39-
export function debounce(fn: () => any, delay: number): () => void {
39+
export function debounce<T extends (...args: any[]) => any>(fn: T, delay: number): (...args: Parameters<T>) => void {
4040
let timer: NodeJS.Timeout | undefined;
4141

42-
return () => {
42+
return (...args: Parameters<T>) => {
4343
if (timer) {
4444
clearTimeout(timer);
4545
}
46-
timer = setTimeout(() => fn(), delay);
46+
timer = setTimeout(() => fn(...args), delay);
4747
};
4848
}

src/github/createPRViewProvider.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { ChangeTemplateReply, DisplayLabel, PreReviewState } from './views';
2121
import { RemoteInfo } from '../../common/types';
2222
import { ChooseBaseRemoteAndBranchResult, ChooseCompareRemoteAndBranchResult, ChooseRemoteAndBranchArgs, CreateParamsNew, CreatePullRequestNew, TitleAndDescriptionArgs } from '../../common/views';
2323
import type { Branch } from '../api/api';
24+
import { debounce } from '../common/async';
2425
import { GitHubServerType } from '../common/authentication';
2526
import { emojify, ensureEmojis } from '../common/emoji';
2627
import { commands, contexts } from '../common/executeCommands';
@@ -967,10 +968,35 @@ export class CreatePullRequestViewProvider extends BaseCreatePullRequestViewProv
967968
const branchPlaceholder = isBase ? vscode.l10n.t('Choose a base branch') : vscode.l10n.t('Choose a branch to merge');
968969
const repositoryPlaceholder = isBase ? vscode.l10n.t('Choose a base repository') : vscode.l10n.t('Choose a repository to merge from');
969970

971+
let updateCounter = 0;
972+
const updateItems = async (githubRepository: GitHubRepository, prefix: string | undefined) => {
973+
const currentUpdate = ++updateCounter;
974+
quickPick.busy = true;
975+
const items = await branchPicks(githubRepository, this._folderRepositoryManager, chooseDifferentRemote, isBase, prefix);
976+
if (currentUpdate === updateCounter) {
977+
quickPick.items = items;
978+
quickPick.busy = false;
979+
}
980+
};
981+
const debounced = debounce(updateItems, 300);
982+
let onDidChangeValueDisposable: vscode.Disposable | undefined;
983+
const addValueChangeListener = () => {
984+
if (githubRepository && !onDidChangeValueDisposable) {
985+
onDidChangeValueDisposable = quickPick.onDidChangeValue(async value => {
986+
return debounced(githubRepository!, value);
987+
});
988+
}
989+
};
990+
addValueChangeListener();
991+
970992
quickPick.placeholder = githubRepository ? branchPlaceholder : remotePlaceholder;
971993
quickPick.show();
972994
quickPick.busy = true;
973-
quickPick.items = githubRepository ? await branchPicks(githubRepository, this._folderRepositoryManager, chooseDifferentRemote, isBase) : await this.remotePicks(isBase);
995+
if (githubRepository) {
996+
await updateItems(githubRepository, undefined);
997+
} else {
998+
quickPick.items = await this.remotePicks(isBase);
999+
}
9741000
const activeItem = message.args.currentBranch ? quickPick.items.find(item => item.branch === message.args.currentBranch) : undefined;
9751001
quickPick.activeItems = activeItem ? [activeItem] : [];
9761002
quickPick.busy = false;
@@ -989,7 +1015,8 @@ export class CreatePullRequestViewProvider extends BaseCreatePullRequestViewProv
9891015
const selectedRemote = selectedPick as vscode.QuickPickItem & { remote: RemoteInfo };
9901016
quickPick.busy = true;
9911017
githubRepository = this._folderRepositoryManager.findRepo(repo => repo.remote.owner === selectedRemote.remote.owner && repo.remote.repositoryName === selectedRemote.remote.repositoryName)!;
992-
quickPick.items = await branchPicks(githubRepository, this._folderRepositoryManager, chooseDifferentRemote, isBase);
1018+
await updateItems(githubRepository, undefined);
1019+
addValueChangeListener();
9931020
quickPick.placeholder = branchPlaceholder;
9941021
quickPick.busy = false;
9951022
} else if (selectedPick.branch && selectedPick.remote) {
@@ -1003,6 +1030,7 @@ export class CreatePullRequestViewProvider extends BaseCreatePullRequestViewProv
10031030
if (!result || !githubRepository) {
10041031
quickPick.hide();
10051032
quickPick.dispose();
1033+
onDidChangeValueDisposable?.dispose();
10061034
return;
10071035
}
10081036

@@ -1011,6 +1039,7 @@ export class CreatePullRequestViewProvider extends BaseCreatePullRequestViewProv
10111039

10121040
quickPick.hide();
10131041
quickPick.dispose();
1042+
onDidChangeValueDisposable?.dispose();
10141043
return this._replyMessage(message, chooseResult);
10151044
}
10161045

src/github/githubRepository.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,7 @@ export class GitHubRepository extends Disposable {
12691269
return data.repository?.ref?.target.oid;
12701270
}
12711271

1272-
async listBranches(owner: string, repositoryName: string): Promise<string[]> {
1272+
async listBranches(owner: string, repositoryName: string, prefix: string | undefined): Promise<string[]> {
12731273
const { query, remote, schema } = await this.ensure();
12741274
Logger.debug(`List branches for ${owner}/${repositoryName} - enter`, this.id);
12751275

@@ -1289,6 +1289,7 @@ export class GitHubRepository extends Disposable {
12891289
name: remote.repositoryName,
12901290
first: 100,
12911291
after: after,
1292+
query: prefix ? prefix : null,
12921293
},
12931294
});
12941295

src/github/pullRequestOverview.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { PullRequestReviewCommon, ReviewContext } from './pullRequestReviewCommo
2626
import { branchPicks, pickEmail, reviewersQuickPick } from './quickPicks';
2727
import { parseReviewers } from './utils';
2828
import { CancelCodingAgentReply, ChangeBaseReply, ChangeReviewersReply, DeleteReviewResult, MergeArguments, MergeResult, PullRequest, ReviewType } from './views';
29+
import { debounce } from '../common/async';
2930
import { COPILOT_ACCOUNTS, IComment } from '../common/comment';
3031
import { COPILOT_REVIEWER, COPILOT_REVIEWER_ACCOUNT, COPILOT_SWE_AGENT, copilotEventToStatus, CopilotPRStatus, mostRecentCopilotEvent } from '../common/copilot';
3132
import { commands, contexts } from '../common/executeCommands';
@@ -923,14 +924,27 @@ export class PullRequestOverviewPanel extends IssueOverviewPanel<PullRequestMode
923924

924925
private async changeBaseBranch(message: IRequestMessage<void>): Promise<void> {
925926
const quickPick = vscode.window.createQuickPick<vscode.QuickPickItem & { branch?: string }>();
927+
let updateCounter = 0;
928+
const updateItems = async (prefix: string | undefined) => {
929+
const currentUpdate = ++updateCounter;
930+
quickPick.busy = true;
931+
const items = await branchPicks(this._item.githubRepository, this._folderRepositoryManager, undefined, true, prefix);
932+
if (currentUpdate === updateCounter) {
933+
quickPick.items = items;
934+
quickPick.busy = false;
935+
}
936+
};
937+
const debounced = debounce(updateItems, 300);
938+
const onDidChangeValueDisposable = quickPick.onDidChangeValue(async value => {
939+
return debounced(value);
940+
});
926941

927942
try {
928943
quickPick.busy = true;
929944
quickPick.canSelectMany = false;
930945
quickPick.placeholder = vscode.l10n.t('Select a new base branch');
931946
quickPick.show();
932-
933-
quickPick.items = await branchPicks(this._item.githubRepository, this._folderRepositoryManager, undefined, true);
947+
await updateItems(undefined);
934948

935949
quickPick.busy = false;
936950
const acceptPromise = asPromise<void>(quickPick.onDidAccept).then(() => {
@@ -961,6 +975,7 @@ export class PullRequestOverviewPanel extends IssueOverviewPanel<PullRequestMode
961975
vscode.window.showErrorMessage(formatError(e));
962976
} finally {
963977
quickPick.hide();
978+
onDidChangeValueDisposable.dispose();
964979
quickPick.dispose();
965980
}
966981
}

src/github/queriesShared.gql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -945,9 +945,9 @@ query GetBranch($owner: String!, $name: String!, $qualifiedName: String!) {
945945
}
946946
}
947947

948-
query ListBranches($owner: String!, $name: String!, $first: Int!, $after: String) {
948+
query ListBranches($owner: String!, $name: String!, $first: Int!, $after: String, $query: String) {
949949
repository(owner: $owner, name: $name) {
950-
refs(first: $first, after: $after, refPrefix: "refs/heads/") {
950+
refs(first: $first, after: $after, refPrefix: "refs/heads/", query: $query) {
951951
nodes {
952952
name
953953
}

src/github/quickPicks.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,11 +482,11 @@ function getRecentlyUsedBranches(folderRepoManager: FolderRepositoryManager, own
482482
return state.branches[repoKey] || [];
483483
}
484484

485-
export async function branchPicks(githubRepository: GitHubRepository, folderRepoManager: FolderRepositoryManager, changeRepoMessage: string | undefined, isBase: boolean): Promise<(vscode.QuickPickItem & { remote?: RemoteInfo, branch?: string })[]> {
485+
export async function branchPicks(githubRepository: GitHubRepository, folderRepoManager: FolderRepositoryManager, changeRepoMessage: string | undefined, isBase: boolean, prefix: string | undefined): Promise<(vscode.QuickPickItem & { remote?: RemoteInfo, branch?: string })[]> {
486486
let branches: (string | Ref)[];
487487
if (isBase) {
488488
// For the base, we only want to show branches from GitHub.
489-
branches = await githubRepository.listBranches(githubRepository.remote.owner, githubRepository.remote.repositoryName);
489+
branches = await githubRepository.listBranches(githubRepository.remote.owner, githubRepository.remote.repositoryName, prefix);
490490
} else {
491491
// For the compare, we only want to show local branches.
492492
branches = (await folderRepoManager.repository.getBranches({ remote: false })).filter(branch => branch.name);

0 commit comments

Comments
 (0)