@@ -28,8 +28,16 @@ import type { GitWorktree } from '../git/models/worktree';
2828import { remoteUrlRegex } from '../git/parsers/remoteParser' ;
2929import type { ContributorQuickPickItem } from '../git/utils/-webview/contributor.quickpick' ;
3030import { createContributorQuickPickItem } from '../git/utils/-webview/contributor.quickpick' ;
31+ import { groupRepositories } from '../git/utils/-webview/repository.utils' ;
3132import type { BranchSortOptions , TagSortOptions } from '../git/utils/-webview/sorting' ;
32- import { sortBranches , sortContributors , sortTags , sortWorktrees } from '../git/utils/-webview/sorting' ;
33+ import {
34+ sortBranches ,
35+ sortContributors ,
36+ sortRepositories ,
37+ sortRepositoriesGrouped ,
38+ sortTags ,
39+ sortWorktrees ,
40+ } from '../git/utils/-webview/sorting' ;
3341import type { WorktreeQuickPickItem } from '../git/utils/-webview/worktree.quickpick' ;
3442import { createWorktreeQuickPickItem } from '../git/utils/-webview/worktree.quickpick' ;
3543import { getWorktreesByBranch } from '../git/utils/-webview/worktree.utils' ;
@@ -1576,43 +1584,49 @@ export function* pickRemotesStep<
15761584export async function * pickRepositoryStep <
15771585 State extends PartialStepState & { repo ?: string | Repository } ,
15781586 Context extends { repos : Repository [ ] ; title : string ; associatedView : ViewsWithRepositoryFolders } ,
1579- > ( state : State , context : Context , placeholder : string = 'Choose a repository' ) : AsyncStepResultGenerator < Repository > {
1587+ > (
1588+ state : State ,
1589+ context : Context ,
1590+ options ?: { excludeWorktrees ?: boolean ; placeholder ?: string } ,
1591+ ) : AsyncStepResultGenerator < Repository > {
15801592 if ( typeof state . repo === 'string' ) {
15811593 state . repo = Container . instance . git . getRepository ( state . repo ) ;
15821594 if ( state . repo != null ) return state . repo ;
15831595 }
1584- let active ;
1585- try {
1586- active = state . repo ?? ( await Container . instance . git . getOrOpenRepositoryForEditor ( ) ) ;
1587- } catch ( ex ) {
1588- Logger . log (
1589- 'pickRepositoryStep: failed to get active repository. Normally it happens when the currently open file does not belong to a repository' ,
1590- ex ,
1591- ) ;
1592- active = undefined ;
1596+
1597+ const active = state . repo ?? ( await Container . instance . git . getOrOpenRepositoryForEditor ( ) ) ;
1598+
1599+ let repos = context . repos ;
1600+ const grouped = await groupRepositories ( repos ) ;
1601+ if ( options ?. excludeWorktrees ) {
1602+ repos = sortRepositories ( [ ... grouped . keys ( ) ] ) ;
1603+ } else {
1604+ repos = sortRepositoriesGrouped ( grouped ) ;
15931605 }
15941606
1607+ const placeholder = options ?. placeholder ?? 'Choose a repository' ;
1608+
15951609 const step = createPickStep < RepositoryQuickPickItem > ( {
15961610 title : context . title ,
1597- placeholder : context . repos . length === 0 ? `${ placeholder } — no opened repositories found` : placeholder ,
1598- items :
1599- context . repos . length === 0
1600- ? [
1601- createDirectiveQuickPickItem ( Directive . Cancel , true , {
1602- label : 'Cancel' ,
1603- detail : 'No opened repositories found' ,
1611+ placeholder : ! repos . length ? `${ placeholder } — no opened repositories found` : placeholder ,
1612+ items : ! repos . length
1613+ ? [
1614+ createDirectiveQuickPickItem ( Directive . Cancel , true , {
1615+ label : 'Cancel' ,
1616+ detail : 'No opened repositories found' ,
1617+ } ) ,
1618+ ]
1619+ : Promise . all (
1620+ repos . map ( r =>
1621+ createRepositoryQuickPickItem ( r , r . id === active ?. id , {
1622+ branch : true ,
1623+ buttons : [ RevealInSideBarQuickInputButton ] ,
1624+ fetched : true ,
1625+ indent : ! grouped . has ( r ) ,
1626+ status : true ,
16041627 } ) ,
1605- ]
1606- : Promise . all (
1607- context . repos . map ( r =>
1608- createRepositoryQuickPickItem ( r , r . id === active ?. id , {
1609- branch : true ,
1610- buttons : [ RevealInSideBarQuickInputButton ] ,
1611- fetched : true ,
1612- status : true ,
1613- } ) ,
1614- ) ,
16151628 ) ,
1629+ ) ,
16161630 onDidClickItemButton : ( _quickpick , button , { item } ) => {
16171631 if ( button === RevealInSideBarQuickInputButton ) {
16181632 void revealRepository ( item . path , context . associatedView , { select : true , focus : false , expand : true } ) ;
@@ -1634,15 +1648,13 @@ export async function* pickRepositoriesStep<
16341648> (
16351649 state : State ,
16361650 context : Context ,
1637- options ?: { placeholder ?: string ; skipIfPossible ?: boolean } ,
1651+ options ?: { excludeWorktrees ?: boolean ; placeholder ?: string ; skipIfPossible ?: boolean } ,
16381652) : AsyncStepResultGenerator < Repository [ ] > {
1639- options = { placeholder : 'Choose repositories' , skipIfPossible : false , ...options } ;
1640-
16411653 let actives : Repository [ ] ;
16421654 if ( state . repos != null ) {
16431655 if ( isStringArray ( state . repos ) ) {
16441656 actives = filterMap ( state . repos , path => context . repos . find ( r => r . path === path ) ) ;
1645- if ( options . skipIfPossible && actives . length !== 0 && state . repos . length === actives . length ) {
1657+ if ( options ? .skipIfPossible && actives . length && state . repos . length === actives . length ) {
16461658 return actives ;
16471659 }
16481660 } else {
@@ -1653,33 +1665,42 @@ export async function* pickRepositoriesStep<
16531665 actives = active != null ? [ active ] : [ ] ;
16541666 }
16551667
1668+ let repos = context . repos ;
1669+ const grouped = await groupRepositories ( repos ) ;
1670+ if ( options ?. excludeWorktrees ) {
1671+ repos = sortRepositories ( [ ...grouped . keys ( ) ] ) ;
1672+ } else {
1673+ repos = sortRepositoriesGrouped ( grouped ) ;
1674+ }
1675+
1676+ const placeholder = options ?. placeholder ?? 'Choose a repository' ;
1677+
16561678 const step = createPickStep < RepositoryQuickPickItem > ( {
16571679 multiselect : true ,
16581680 title : context . title ,
1659- placeholder :
1660- context . repos . length === 0 ? `${ options . placeholder } — no opened repositories found` : options . placeholder ,
1661- items :
1662- context . repos . length === 0
1663- ? [
1664- createDirectiveQuickPickItem ( Directive . Cancel , true , {
1665- label : 'Cancel' ,
1666- detail : 'No opened repositories found' ,
1667- } ) ,
1668- ]
1669- : Promise . all (
1670- context . repos . map ( repo =>
1671- createRepositoryQuickPickItem (
1672- repo ,
1673- actives . some ( r => r . id === repo . id ) ,
1674- {
1675- branch : true ,
1676- buttons : [ RevealInSideBarQuickInputButton ] ,
1677- fetched : true ,
1678- status : true ,
1679- } ,
1680- ) ,
1681+ placeholder : ! repos . length ? `${ placeholder } — no opened repositories found` : placeholder ,
1682+ items : ! repos . length
1683+ ? [
1684+ createDirectiveQuickPickItem ( Directive . Cancel , true , {
1685+ label : 'Cancel' ,
1686+ detail : 'No opened repositories found' ,
1687+ } ) ,
1688+ ]
1689+ : Promise . all (
1690+ repos . map ( repo =>
1691+ createRepositoryQuickPickItem (
1692+ repo ,
1693+ actives . some ( r => r . id === repo . id ) ,
1694+ {
1695+ branch : true ,
1696+ buttons : [ RevealInSideBarQuickInputButton ] ,
1697+ fetched : true ,
1698+ indent : ! grouped . has ( repo ) ,
1699+ status : true ,
1700+ } ,
16811701 ) ,
16821702 ) ,
1703+ ) ,
16831704 onDidClickItemButton : ( _quickpick , button , { item } ) => {
16841705 if ( button === RevealInSideBarQuickInputButton ) {
16851706 void revealRepository ( item . path , context . associatedView , { select : true , focus : false , expand : true } ) ;
0 commit comments