@@ -28,8 +28,16 @@ import type { GitWorktree } from '../git/models/worktree';
28
28
import { remoteUrlRegex } from '../git/parsers/remoteParser' ;
29
29
import type { ContributorQuickPickItem } from '../git/utils/-webview/contributor.quickpick' ;
30
30
import { createContributorQuickPickItem } from '../git/utils/-webview/contributor.quickpick' ;
31
+ import { groupRepositories } from '../git/utils/-webview/repository.utils' ;
31
32
import 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' ;
33
41
import type { WorktreeQuickPickItem } from '../git/utils/-webview/worktree.quickpick' ;
34
42
import { createWorktreeQuickPickItem } from '../git/utils/-webview/worktree.quickpick' ;
35
43
import { getWorktreesByBranch } from '../git/utils/-webview/worktree.utils' ;
@@ -1577,43 +1585,49 @@ export function* pickRemotesStep<
1577
1585
export async function * pickRepositoryStep <
1578
1586
State extends PartialStepState & { repo ?: string | Repository } ,
1579
1587
Context extends { repos : Repository [ ] ; title : string ; associatedView : ViewsWithRepositoryFolders } ,
1580
- > ( state : State , context : Context , placeholder : string = 'Choose a repository' ) : AsyncStepResultGenerator < Repository > {
1588
+ > (
1589
+ state : State ,
1590
+ context : Context ,
1591
+ options ?: { excludeWorktrees ?: boolean ; placeholder ?: string } ,
1592
+ ) : AsyncStepResultGenerator < Repository > {
1581
1593
if ( typeof state . repo === 'string' ) {
1582
1594
state . repo = Container . instance . git . getRepository ( state . repo ) ;
1583
1595
if ( state . repo != null ) return state . repo ;
1584
1596
}
1585
- let active ;
1586
- try {
1587
- active = state . repo ?? ( await Container . instance . git . getOrOpenRepositoryForEditor ( ) ) ;
1588
- } catch ( ex ) {
1589
- Logger . log (
1590
- 'pickRepositoryStep: failed to get active repository. Normally it happens when the currently open file does not belong to a repository' ,
1591
- ex ,
1592
- ) ;
1593
- active = undefined ;
1597
+
1598
+ const active = state . repo ?? ( await Container . instance . git . getOrOpenRepositoryForEditor ( ) ) ;
1599
+
1600
+ let repos = context . repos ;
1601
+ const grouped = await groupRepositories ( repos ) ;
1602
+ if ( options ?. excludeWorktrees ) {
1603
+ repos = sortRepositories ( [ ... grouped . keys ( ) ] ) ;
1604
+ } else {
1605
+ repos = sortRepositoriesGrouped ( grouped ) ;
1594
1606
}
1595
1607
1608
+ const placeholder = options ?. placeholder ?? 'Choose a repository' ;
1609
+
1596
1610
const step = createPickStep < RepositoryQuickPickItem > ( {
1597
1611
title : context . title ,
1598
- placeholder : context . repos . length === 0 ? `${ placeholder } — no opened repositories found` : placeholder ,
1599
- items :
1600
- context . repos . length === 0
1601
- ? [
1602
- createDirectiveQuickPickItem ( Directive . Cancel , true , {
1603
- label : 'Cancel' ,
1604
- detail : 'No opened repositories found' ,
1612
+ placeholder : ! repos . length ? `${ placeholder } — no opened repositories found` : placeholder ,
1613
+ items : ! repos . length
1614
+ ? [
1615
+ createDirectiveQuickPickItem ( Directive . Cancel , true , {
1616
+ label : 'Cancel' ,
1617
+ detail : 'No opened repositories found' ,
1618
+ } ) ,
1619
+ ]
1620
+ : Promise . all (
1621
+ repos . map ( r =>
1622
+ createRepositoryQuickPickItem ( r , r . id === active ?. id , {
1623
+ branch : true ,
1624
+ buttons : [ RevealInSideBarQuickInputButton ] ,
1625
+ fetched : true ,
1626
+ indent : ! grouped . has ( r ) ,
1627
+ status : true ,
1605
1628
} ) ,
1606
- ]
1607
- : Promise . all (
1608
- context . repos . map ( r =>
1609
- createRepositoryQuickPickItem ( r , r . id === active ?. id , {
1610
- branch : true ,
1611
- buttons : [ RevealInSideBarQuickInputButton ] ,
1612
- fetched : true ,
1613
- status : true ,
1614
- } ) ,
1615
- ) ,
1616
1629
) ,
1630
+ ) ,
1617
1631
onDidClickItemButton : ( _quickpick , button , { item } ) => {
1618
1632
if ( button === RevealInSideBarQuickInputButton ) {
1619
1633
void revealRepository ( item . path , context . associatedView , { select : true , focus : false , expand : true } ) ;
@@ -1635,15 +1649,13 @@ export async function* pickRepositoriesStep<
1635
1649
> (
1636
1650
state : State ,
1637
1651
context : Context ,
1638
- options ?: { placeholder ?: string ; skipIfPossible ?: boolean } ,
1652
+ options ?: { excludeWorktrees ?: boolean ; placeholder ?: string ; skipIfPossible ?: boolean } ,
1639
1653
) : AsyncStepResultGenerator < Repository [ ] > {
1640
- options = { placeholder : 'Choose repositories' , skipIfPossible : false , ...options } ;
1641
-
1642
1654
let actives : Repository [ ] ;
1643
1655
if ( state . repos != null ) {
1644
1656
if ( isStringArray ( state . repos ) ) {
1645
1657
actives = filterMap ( state . repos , path => context . repos . find ( r => r . path === path ) ) ;
1646
- if ( options . skipIfPossible && actives . length !== 0 && state . repos . length === actives . length ) {
1658
+ if ( options ? .skipIfPossible && actives . length && state . repos . length === actives . length ) {
1647
1659
return actives ;
1648
1660
}
1649
1661
} else {
@@ -1654,33 +1666,42 @@ export async function* pickRepositoriesStep<
1654
1666
actives = active != null ? [ active ] : [ ] ;
1655
1667
}
1656
1668
1669
+ let repos = context . repos ;
1670
+ const grouped = await groupRepositories ( repos ) ;
1671
+ if ( options ?. excludeWorktrees ) {
1672
+ repos = sortRepositories ( [ ...grouped . keys ( ) ] ) ;
1673
+ } else {
1674
+ repos = sortRepositoriesGrouped ( grouped ) ;
1675
+ }
1676
+
1677
+ const placeholder = options ?. placeholder ?? 'Choose a repository' ;
1678
+
1657
1679
const step = createPickStep < RepositoryQuickPickItem > ( {
1658
1680
multiselect : true ,
1659
1681
title : context . title ,
1660
- placeholder :
1661
- context . repos . length === 0 ? `${ options . placeholder } — no opened repositories found` : options . placeholder ,
1662
- items :
1663
- context . repos . length === 0
1664
- ? [
1665
- createDirectiveQuickPickItem ( Directive . Cancel , true , {
1666
- label : 'Cancel' ,
1667
- detail : 'No opened repositories found' ,
1668
- } ) ,
1669
- ]
1670
- : Promise . all (
1671
- context . repos . map ( repo =>
1672
- createRepositoryQuickPickItem (
1673
- repo ,
1674
- actives . some ( r => r . id === repo . id ) ,
1675
- {
1676
- branch : true ,
1677
- buttons : [ RevealInSideBarQuickInputButton ] ,
1678
- fetched : true ,
1679
- status : true ,
1680
- } ,
1681
- ) ,
1682
+ placeholder : ! repos . length ? `${ placeholder } — no opened repositories found` : placeholder ,
1683
+ items : ! repos . length
1684
+ ? [
1685
+ createDirectiveQuickPickItem ( Directive . Cancel , true , {
1686
+ label : 'Cancel' ,
1687
+ detail : 'No opened repositories found' ,
1688
+ } ) ,
1689
+ ]
1690
+ : Promise . all (
1691
+ repos . map ( repo =>
1692
+ createRepositoryQuickPickItem (
1693
+ repo ,
1694
+ actives . some ( r => r . id === repo . id ) ,
1695
+ {
1696
+ branch : true ,
1697
+ buttons : [ RevealInSideBarQuickInputButton ] ,
1698
+ fetched : true ,
1699
+ indent : ! grouped . has ( repo ) ,
1700
+ status : true ,
1701
+ } ,
1682
1702
) ,
1683
1703
) ,
1704
+ ) ,
1684
1705
onDidClickItemButton : ( _quickpick , button , { item } ) => {
1685
1706
if ( button === RevealInSideBarQuickInputButton ) {
1686
1707
void revealRepository ( item . path , context . associatedView , { select : true , focus : false , expand : true } ) ;
0 commit comments