Browse Source

Fixes view item revealing

Adds proper reveal to repo folders
Adds reveal to contributors git commands
main
Eric Amodio 3 years ago
parent
commit
0d3a6dc7ee
33 changed files with 535 additions and 151 deletions
  1. +7
    -0
      package.json
  2. +3
    -0
      src/commands/git/branch.ts
  3. +3
    -0
      src/commands/git/cherry-pick.ts
  4. +3
    -0
      src/commands/git/coauthors.ts
  5. +3
    -0
      src/commands/git/fetch.ts
  6. +3
    -0
      src/commands/git/log.ts
  7. +3
    -0
      src/commands/git/merge.ts
  8. +3
    -0
      src/commands/git/pull.ts
  9. +3
    -0
      src/commands/git/push.ts
  10. +3
    -0
      src/commands/git/rebase.ts
  11. +3
    -0
      src/commands/git/reset.ts
  12. +3
    -0
      src/commands/git/revert.ts
  13. +3
    -0
      src/commands/git/search.ts
  14. +3
    -0
      src/commands/git/show.ts
  15. +3
    -0
      src/commands/git/stash.ts
  16. +3
    -0
      src/commands/git/status.ts
  17. +3
    -0
      src/commands/git/switch.ts
  18. +3
    -0
      src/commands/git/tag.ts
  19. +86
    -79
      src/commands/gitCommands.actions.ts
  20. +36
    -21
      src/commands/quickCommand.steps.ts
  21. +1
    -0
      src/config.ts
  22. +11
    -9
      src/git/models/models.ts
  23. +5
    -4
      src/quickpicks/gitQuickPickItems.ts
  24. +24
    -3
      src/views/branchesView.ts
  25. +23
    -2
      src/views/commitsView.ts
  26. +86
    -5
      src/views/contributorsView.ts
  27. +1
    -1
      src/views/lineHistoryView.ts
  28. +25
    -4
      src/views/remotesView.ts
  29. +107
    -16
      src/views/repositoriesView.ts
  30. +19
    -1
      src/views/searchAndCompareView.ts
  31. +23
    -2
      src/views/stashesView.ts
  32. +23
    -2
      src/views/tagsView.ts
  33. +7
    -2
      src/views/viewBase.ts

+ 7
- 0
package.json View File

@ -1614,6 +1614,13 @@
"markdownDescription": "Specifies whether to show avatar images instead of commit (or status) icons in the _Contributors_ view", "markdownDescription": "Specifies whether to show avatar images instead of commit (or status) icons in the _Contributors_ view",
"scope": "window", "scope": "window",
"order": 60 "order": 60
},
"gitlens.views.contributors.reveal": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to reveal contributors in the _Contributors_ view, otherwise they revealed in the _Repositories_ view",
"scope": "window",
"order": 20
} }
} }
}, },

+ 3
- 0
src/commands/git/branch.ts View File

@ -4,6 +4,7 @@ import { Container } from '../../container';
import { GitBranchReference, GitReference, Repository } from '../../git/git'; import { GitBranchReference, GitReference, Repository } from '../../git/git';
import { FlagsQuickPickItem, QuickPickItemOfT } from '../../quickpicks'; import { FlagsQuickPickItem, QuickPickItemOfT } from '../../quickpicks';
import { Strings } from '../../system'; import { Strings } from '../../system';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
appendReposToTitle, appendReposToTitle,
AsyncStepResultGenerator, AsyncStepResultGenerator,
@ -24,6 +25,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
showTags: boolean; showTags: boolean;
title: string; title: string;
} }
@ -148,6 +150,7 @@ export class BranchGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
associatedView: Container.instance.branchesView,
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
showTags: false, showTags: false,
title: this.title, title: this.title,

+ 3
- 0
src/commands/git/cherry-pick.ts View File

@ -2,6 +2,7 @@
import { Container } from '../../container'; import { Container } from '../../container';
import { GitBranch, GitLog, GitReference, GitRevision, Repository } from '../../git/git'; import { GitBranch, GitLog, GitReference, GitRevision, Repository } from '../../git/git';
import { FlagsQuickPickItem } from '../../quickpicks'; import { FlagsQuickPickItem } from '../../quickpicks';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
appendReposToTitle, appendReposToTitle,
PartialStepState, PartialStepState,
@ -19,6 +20,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
cache: Map<string, Promise<GitLog | undefined>>; cache: Map<string, Promise<GitLog | undefined>>;
destination: GitBranch; destination: GitBranch;
selectedBranchOrTag: GitReference | undefined; selectedBranchOrTag: GitReference | undefined;
@ -81,6 +83,7 @@ export class CherryPickGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.commitsView,
cache: new Map<string, Promise<GitLog | undefined>>(), cache: new Map<string, Promise<GitLog | undefined>>(),
destination: undefined!, destination: undefined!,
selectedBranchOrTag: undefined, selectedBranchOrTag: undefined,

+ 3
- 0
src/commands/git/coauthors.ts View File

@ -3,6 +3,7 @@ import { commands } from 'vscode';
import { Container } from '../../container'; import { Container } from '../../container';
import { GitContributor, Repository } from '../../git/git'; import { GitContributor, Repository } from '../../git/git';
import { Strings } from '../../system'; import { Strings } from '../../system';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
PartialStepState, PartialStepState,
pickContributorsStep, pickContributorsStep,
@ -16,6 +17,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
activeRepo: Repository | undefined; activeRepo: Repository | undefined;
associatedView: ViewsWithRepositoryFolders;
title: string; title: string;
} }
@ -94,6 +96,7 @@ export class CoAuthorsGitCommand extends QuickCommand {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
activeRepo: undefined, activeRepo: undefined,
associatedView: Container.instance.contributorsView,
title: this.title, title: this.title,
}; };

+ 3
- 0
src/commands/git/fetch.ts View File

@ -4,6 +4,7 @@ import { Container } from '../../container';
import { GitBranchReference, GitReference, Repository } from '../../git/git'; import { GitBranchReference, GitReference, Repository } from '../../git/git';
import { FlagsQuickPickItem } from '../../quickpicks'; import { FlagsQuickPickItem } from '../../quickpicks';
import { Arrays, Dates, Strings } from '../../system'; import { Arrays, Dates, Strings } from '../../system';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
appendReposToTitle, appendReposToTitle,
AsyncStepResultGenerator, AsyncStepResultGenerator,
@ -19,6 +20,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
title: string; title: string;
} }
@ -68,6 +70,7 @@ export class FetchGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.commitsView,
title: this.title, title: this.title,
}; };

+ 3
- 0
src/commands/git/log.ts View File

@ -4,6 +4,7 @@ import { Container } from '../../container';
import { GitLog, GitLogCommit, GitReference, Repository } from '../../git/git'; import { GitLog, GitLogCommit, GitReference, Repository } from '../../git/git';
import { GitUri } from '../../git/gitUri'; import { GitUri } from '../../git/gitUri';
import { Strings } from '../../system'; import { Strings } from '../../system';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { GitCommandsCommand } from '../gitCommands'; import { GitCommandsCommand } from '../gitCommands';
import { import {
PartialStepState, PartialStepState,
@ -18,6 +19,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
cache: Map<string, Promise<GitLog | undefined>>; cache: Map<string, Promise<GitLog | undefined>>;
selectedBranchOrTag: GitReference | undefined; selectedBranchOrTag: GitReference | undefined;
title: string; title: string;
@ -77,6 +79,7 @@ export class LogGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.commitsView,
cache: new Map<string, Promise<GitLog | undefined>>(), cache: new Map<string, Promise<GitLog | undefined>>(),
selectedBranchOrTag: undefined, selectedBranchOrTag: undefined,
title: this.title, title: this.title,

+ 3
- 0
src/commands/git/merge.ts View File

@ -3,6 +3,7 @@ import { Container } from '../../container';
import { GitBranch, GitLog, GitReference, GitRevision, Repository } from '../../git/git'; import { GitBranch, GitLog, GitReference, GitRevision, Repository } from '../../git/git';
import { Directive, DirectiveQuickPickItem, FlagsQuickPickItem } from '../../quickpicks'; import { Directive, DirectiveQuickPickItem, FlagsQuickPickItem } from '../../quickpicks';
import { Strings } from '../../system'; import { Strings } from '../../system';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
appendReposToTitle, appendReposToTitle,
AsyncStepResultGenerator, AsyncStepResultGenerator,
@ -21,6 +22,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
cache: Map<string, Promise<GitLog | undefined>>; cache: Map<string, Promise<GitLog | undefined>>;
destination: GitBranch; destination: GitBranch;
pickCommit: boolean; pickCommit: boolean;
@ -78,6 +80,7 @@ export class MergeGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.commitsView,
cache: new Map<string, Promise<GitLog | undefined>>(), cache: new Map<string, Promise<GitLog | undefined>>(),
destination: undefined!, destination: undefined!,
pickCommit: false, pickCommit: false,

+ 3
- 0
src/commands/git/pull.ts View File

@ -4,6 +4,7 @@ import { Container } from '../../container';
import { GitBranch, GitBranchReference, GitReference, Repository } from '../../git/git'; import { GitBranch, GitBranchReference, GitReference, Repository } from '../../git/git';
import { Directive, DirectiveQuickPickItem, FlagsQuickPickItem } from '../../quickpicks'; import { Directive, DirectiveQuickPickItem, FlagsQuickPickItem } from '../../quickpicks';
import { Arrays, Dates, Strings } from '../../system'; import { Arrays, Dates, Strings } from '../../system';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
appendReposToTitle, appendReposToTitle,
AsyncStepResultGenerator, AsyncStepResultGenerator,
@ -20,6 +21,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
title: string; title: string;
} }
@ -74,6 +76,7 @@ export class PullGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.commitsView,
title: this.title, title: this.title,
}; };

+ 3
- 0
src/commands/git/push.ts View File

@ -5,6 +5,7 @@ import { Container } from '../../container';
import { GitBranch, GitBranchReference, GitReference, Repository } from '../../git/git'; import { GitBranch, GitBranchReference, GitReference, Repository } from '../../git/git';
import { Directive, DirectiveQuickPickItem, FlagsQuickPickItem } from '../../quickpicks'; import { Directive, DirectiveQuickPickItem, FlagsQuickPickItem } from '../../quickpicks';
import { Arrays, Dates, Strings } from '../../system'; import { Arrays, Dates, Strings } from '../../system';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
appendReposToTitle, appendReposToTitle,
AsyncStepResultGenerator, AsyncStepResultGenerator,
@ -22,6 +23,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
title: string; title: string;
} }
@ -80,6 +82,7 @@ export class PushGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.commitsView,
title: this.title, title: this.title,
}; };

+ 3
- 0
src/commands/git/rebase.ts View File

@ -4,6 +4,7 @@ import { Container } from '../../container';
import { GitBranch, GitLog, GitReference, GitRevision, Repository } from '../../git/git'; import { GitBranch, GitLog, GitReference, GitRevision, Repository } from '../../git/git';
import { Directive, DirectiveQuickPickItem, FlagsQuickPickItem } from '../../quickpicks'; import { Directive, DirectiveQuickPickItem, FlagsQuickPickItem } from '../../quickpicks';
import { Strings } from '../../system'; import { Strings } from '../../system';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
appendReposToTitle, appendReposToTitle,
AsyncStepResultGenerator, AsyncStepResultGenerator,
@ -22,6 +23,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
cache: Map<string, Promise<GitLog | undefined>>; cache: Map<string, Promise<GitLog | undefined>>;
destination: GitBranch; destination: GitBranch;
pickCommit: boolean; pickCommit: boolean;
@ -99,6 +101,7 @@ export class RebaseGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.commitsView,
cache: new Map<string, Promise<GitLog | undefined>>(), cache: new Map<string, Promise<GitLog | undefined>>(),
destination: undefined!, destination: undefined!,
pickCommit: false, pickCommit: false,

+ 3
- 0
src/commands/git/reset.ts View File

@ -2,6 +2,7 @@
import { Container } from '../../container'; import { Container } from '../../container';
import { GitBranch, GitLog, GitReference, GitRevisionReference, Repository } from '../../git/git'; import { GitBranch, GitLog, GitReference, GitRevisionReference, Repository } from '../../git/git';
import { FlagsQuickPickItem } from '../../quickpicks'; import { FlagsQuickPickItem } from '../../quickpicks';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
appendReposToTitle, appendReposToTitle,
PartialStepState, PartialStepState,
@ -18,6 +19,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
cache: Map<string, Promise<GitLog | undefined>>; cache: Map<string, Promise<GitLog | undefined>>;
destination: GitBranch; destination: GitBranch;
title: string; title: string;
@ -72,6 +74,7 @@ export class ResetGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.commitsView,
cache: new Map<string, Promise<GitLog | undefined>>(), cache: new Map<string, Promise<GitLog | undefined>>(),
destination: undefined!, destination: undefined!,
title: this.title, title: this.title,

+ 3
- 0
src/commands/git/revert.ts View File

@ -2,6 +2,7 @@
import { Container } from '../../container'; import { Container } from '../../container';
import { GitBranch, GitLog, GitReference, GitRevisionReference, Repository } from '../../git/git'; import { GitBranch, GitLog, GitReference, GitRevisionReference, Repository } from '../../git/git';
import { FlagsQuickPickItem } from '../../quickpicks'; import { FlagsQuickPickItem } from '../../quickpicks';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
appendReposToTitle, appendReposToTitle,
PartialStepState, PartialStepState,
@ -18,6 +19,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
cache: Map<string, Promise<GitLog | undefined>>; cache: Map<string, Promise<GitLog | undefined>>;
destination: GitBranch; destination: GitBranch;
title: string; title: string;
@ -74,6 +76,7 @@ export class RevertGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.commitsView,
cache: new Map<string, Promise<GitLog | undefined>>(), cache: new Map<string, Promise<GitLog | undefined>>(),
destination: undefined!, destination: undefined!,
title: this.title, title: this.title,

+ 3
- 0
src/commands/git/search.ts View File

@ -5,6 +5,7 @@ import { GitLog, GitLogCommit, Repository, SearchOperators, searchOperators, Sea
import { ActionQuickPickItem, QuickPickItemOfT } from '../../quickpicks'; import { ActionQuickPickItem, QuickPickItemOfT } from '../../quickpicks';
import { Strings } from '../../system'; import { Strings } from '../../system';
import { SearchResultsNode } from '../../views/nodes'; import { SearchResultsNode } from '../../views/nodes';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { GitCommandsCommand } from '../gitCommands'; import { GitCommandsCommand } from '../gitCommands';
import { import {
appendReposToTitle, appendReposToTitle,
@ -22,6 +23,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
commit: GitLogCommit | undefined; commit: GitLogCommit | undefined;
resultsKey: string | undefined; resultsKey: string | undefined;
resultsPromise: Promise<GitLog | undefined> | undefined; resultsPromise: Promise<GitLog | undefined> | undefined;
@ -92,6 +94,7 @@ export class SearchGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.searchAndCompareView,
commit: undefined, commit: undefined,
resultsKey: undefined, resultsKey: undefined,
resultsPromise: undefined, resultsPromise: undefined,

+ 3
- 0
src/commands/git/show.ts View File

@ -2,6 +2,7 @@
import { Container } from '../../container'; import { Container } from '../../container';
import { GitAuthor, GitLogCommit, GitRevisionReference, GitStashCommit, Repository } from '../../git/git'; import { GitAuthor, GitLogCommit, GitRevisionReference, GitStashCommit, Repository } from '../../git/git';
import { CommandQuickPickItem, CommitFilesQuickPickItem, GitCommandQuickPickItem } from '../../quickpicks'; import { CommandQuickPickItem, CommitFilesQuickPickItem, GitCommandQuickPickItem } from '../../quickpicks';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
PartialStepState, PartialStepState,
pickCommitStep, pickCommitStep,
@ -17,6 +18,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
title: string; title: string;
} }
@ -77,6 +79,7 @@ export class ShowGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.commitsView,
title: this.title, title: this.title,
}; };

+ 3
- 0
src/commands/git/stash.ts View File

@ -8,6 +8,7 @@ import { Logger } from '../../logger';
import { Messages } from '../../messages'; import { Messages } from '../../messages';
import { FlagsQuickPickItem, QuickPickItemOfT } from '../../quickpicks'; import { FlagsQuickPickItem, QuickPickItemOfT } from '../../quickpicks';
import { Strings } from '../../system'; import { Strings } from '../../system';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { GitActions, GitCommandsCommand } from '../gitCommands'; import { GitActions, GitCommandsCommand } from '../gitCommands';
import { import {
appendReposToTitle, appendReposToTitle,
@ -27,6 +28,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
title: string; title: string;
} }
@ -145,6 +147,7 @@ export class StashGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.stashesView,
title: this.title, title: this.title,
}; };

+ 3
- 0
src/commands/git/status.ts View File

@ -4,6 +4,7 @@ import { Container } from '../../container';
import { GitReference, GitStatus, Repository } from '../../git/git'; import { GitReference, GitStatus, Repository } from '../../git/git';
import { CommandQuickPickItem, GitCommandQuickPickItem } from '../../quickpicks'; import { CommandQuickPickItem, GitCommandQuickPickItem } from '../../quickpicks';
import { Strings } from '../../system'; import { Strings } from '../../system';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
PartialStepState, PartialStepState,
pickRepositoryStep, pickRepositoryStep,
@ -16,6 +17,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
status: GitStatus; status: GitStatus;
title: string; title: string;
} }
@ -56,6 +58,7 @@ export class StatusGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.commitsView,
status: undefined!, status: undefined!,
title: this.title, title: this.title,
}; };

+ 3
- 0
src/commands/git/switch.ts View File

@ -4,6 +4,7 @@ import { BranchSorting } from '../../config';
import { Container } from '../../container'; import { Container } from '../../container';
import { GitReference, Repository } from '../../git/git'; import { GitReference, Repository } from '../../git/git';
import { Arrays } from '../../system'; import { Arrays } from '../../system';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
appendReposToTitle, appendReposToTitle,
inputBranchNameStep, inputBranchNameStep,
@ -21,6 +22,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
showTags: boolean; showTags: boolean;
title: string; title: string;
} }
@ -89,6 +91,7 @@ export class SwitchGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.commitsView,
showTags: false, showTags: false,
title: this.title, title: this.title,
}; };

+ 3
- 0
src/commands/git/tag.ts View File

@ -4,6 +4,7 @@ import { Container } from '../../container';
import { GitReference, GitTagReference, Repository } from '../../git/git'; import { GitReference, GitTagReference, Repository } from '../../git/git';
import { FlagsQuickPickItem, QuickPickItemOfT } from '../../quickpicks'; import { FlagsQuickPickItem, QuickPickItemOfT } from '../../quickpicks';
import { Strings } from '../../system'; import { Strings } from '../../system';
import { ViewsWithRepositoryFolders } from '../../views/viewBase';
import { import {
appendReposToTitle, appendReposToTitle,
AsyncStepResultGenerator, AsyncStepResultGenerator,
@ -23,6 +24,7 @@ import {
interface Context { interface Context {
repos: Repository[]; repos: Repository[];
associatedView: ViewsWithRepositoryFolders;
showTags: boolean; showTags: boolean;
title: string; title: string;
} }
@ -128,6 +130,7 @@ export class TagGitCommand extends QuickCommand {
protected async *steps(state: PartialStepState<State>): StepGenerator { protected async *steps(state: PartialStepState<State>): StepGenerator {
const context: Context = { const context: Context = {
repos: Container.instance.git.openRepositories, repos: Container.instance.git.openRepositories,
associatedView: Container.instance.tagsView,
showTags: false, showTags: false,
title: this.title, title: this.title,
}; };

+ 86
- 79
src/commands/gitCommands.actions.ts View File

@ -11,7 +11,7 @@ import {
GitCommandsCommandArgs, GitCommandsCommandArgs,
OpenWorkingFileCommandArgs, OpenWorkingFileCommandArgs,
} from '../commands'; } from '../commands';
import { configuration, FileAnnotationType } from '../configuration';
import { FileAnnotationType } from '../configuration';
import { Container } from '../container'; import { Container } from '../container';
import { import {
GitBranchReference, GitBranchReference,
@ -28,6 +28,7 @@ import {
} from '../git/git'; } from '../git/git';
import { GitUri } from '../git/gitUri'; import { GitUri } from '../git/gitUri';
import { RepositoryPicker } from '../quickpicks'; import { RepositoryPicker } from '../quickpicks';
import { ViewsWithRepositoryFolders } from '../views/viewBase';
import { ResetGitCommandArgs } from './git/reset'; import { ResetGitCommandArgs } from './git/reset';
export async function executeGitCommand(args: GitCommandsCommandArgs): Promise<void> { export async function executeGitCommand(args: GitCommandsCommandArgs): Promise<void> {
@ -150,21 +151,10 @@ export namespace GitActions {
expand?: boolean | number; expand?: boolean | number;
}, },
) { ) {
if (
!configuration.get(`views.${branch.remote ? 'remotes' : 'branches'}.reveal` as const) ||
(Container.instance.repositoriesView.visible &&
!(branch.remote ? Container.instance.remotesView.visible : Container.instance.branchesView.visible))
) {
return Container.instance.repositoriesView.revealBranch(branch, options);
}
let node;
if (branch.remote) {
node = await Container.instance.remotesView.revealBranch(branch, options);
} else {
node = await Container.instance.branchesView.revealBranch(branch, options);
}
const view = branch.remote ? Container.instance.remotesView : Container.instance.branchesView;
const node = view.canReveal
? await view.revealBranch(branch, options)
: await Container.instance.repositoriesView.revealBranch(branch, options);
return node; return node;
} }
} }
@ -650,23 +640,20 @@ export namespace GitActions {
expand?: boolean | number; expand?: boolean | number;
}, },
) { ) {
if (
!configuration.get('views.commits.reveal') ||
(Container.instance.repositoriesView.visible && !Container.instance.commitsView.visible)
) {
return Container.instance.repositoriesView.revealCommit(commit, options);
}
const views = [
Container.instance.commitsView,
Container.instance.branchesView,
Container.instance.remotesView,
];
// TODO@eamodio stop duplicate notifications // TODO@eamodio stop duplicate notifications
let node = await Container.instance.commitsView.revealCommit(commit, options);
if (node != null) return node;
node = await Container.instance.branchesView.revealCommit(commit, options);
if (node != null) return node;
node = await Container.instance.remotesView.revealCommit(commit, options);
if (node != null) return node;
for (const view of views) {
const node = view.canReveal
? await view.revealCommit(commit, options)
: await Container.instance.repositoriesView.revealCommit(commit, options);
if (node != null) return node;
}
return undefined; return undefined;
} }
@ -679,48 +666,19 @@ export namespace GitActions {
state: { repo: repo, contributors: contributors }, state: { repo: repo, contributors: contributors },
}); });
} }
}
export namespace Tag {
export function create(repo?: string | Repository, ref?: GitReference, name?: string) {
return executeGitCommand({
command: 'tag',
state: {
subcommand: 'create',
repo: repo,
reference: ref,
name: name,
},
});
}
export function remove(repo?: string | Repository, refs?: GitTagReference | GitTagReference[]) {
return executeGitCommand({
command: 'tag',
state: {
subcommand: 'delete',
repo: repo,
references: refs,
},
});
}
export async function reveal( export async function reveal(
tag: GitTagReference,
contributor: GitContributor,
options?: { options?: {
select?: boolean; select?: boolean;
focus?: boolean; focus?: boolean;
expand?: boolean | number; expand?: boolean | number;
}, },
) { ) {
if (
!configuration.get('views.tags.reveal') ||
(Container.instance.repositoriesView.visible && !Container.instance.tagsView.visible)
) {
return Container.instance.repositoriesView.revealTag(tag, options);
}
const node = await Container.instance.tagsView.revealTag(tag, options);
const view = Container.instance.contributorsView;
const node = view.canReveal
? await view.revealContributor(contributor, options)
: await Container.instance.repositoriesView.revealContributor(contributor, options);
return node; return node;
} }
} }
@ -783,14 +741,27 @@ export namespace GitActions {
expand?: boolean | number; expand?: boolean | number;
}, },
) { ) {
// if (
// configuration.get('views.repositories.enabled') &&
// (Container.instance.repositoriesView.visible || !Container.instance.remotesView.visible)
// ) {
// return Container.instance.repositoriesView.revealRemote(remote, options);
// }
const node = await Container.instance.remotesView.revealRemote(remote, options);
const view = Container.instance.remotesView;
const node = view.canReveal
? await view.revealRemote(remote, options)
: await Container.instance.repositoriesView.revealRemote(remote, options);
return node;
}
}
export namespace Repository {
export async function reveal(
repoPath: string,
view?: ViewsWithRepositoryFolders,
options?: {
select?: boolean;
focus?: boolean;
expand?: boolean | number;
},
) {
const node = view?.canReveal
? await view.revealRepository(repoPath, options)
: await Container.instance.repositoriesView.revealRepository(repoPath, options);
return node; return node;
} }
} }
@ -838,14 +809,50 @@ export namespace GitActions {
expand?: boolean | number; expand?: boolean | number;
}, },
) { ) {
if (
!configuration.get('views.stashes.reveal') ||
(Container.instance.repositoriesView.visible && !Container.instance.stashesView.visible)
) {
return Container.instance.repositoriesView.revealStash(stash, options);
}
const view = Container.instance.stashesView;
const node = view.canReveal
? await view.revealStash(stash, options)
: await Container.instance.repositoriesView.revealStash(stash, options);
return node;
}
}
export namespace Tag {
export function create(repo?: string | Repository, ref?: GitReference, name?: string) {
return executeGitCommand({
command: 'tag',
state: {
subcommand: 'create',
repo: repo,
reference: ref,
name: name,
},
});
}
const node = await Container.instance.stashesView.revealStash(stash, options);
export function remove(repo?: string | Repository, refs?: GitTagReference | GitTagReference[]) {
return executeGitCommand({
command: 'tag',
state: {
subcommand: 'delete',
repo: repo,
references: refs,
},
});
}
export async function reveal(
tag: GitTagReference,
options?: {
select?: boolean;
focus?: boolean;
expand?: boolean | number;
},
) {
const view = Container.instance.tagsView;
const node = view.canReveal
? await view.revealTag(tag, options)
: await Container.instance.repositoriesView.revealTag(tag, options);
return node; return node;
} }
} }

+ 36
- 21
src/commands/quickCommand.steps.ts View File

@ -67,6 +67,7 @@ import {
TagQuickPickItem, TagQuickPickItem,
} from '../quickpicks'; } from '../quickpicks';
import { Arrays, Iterables, Strings } from '../system'; import { Arrays, Iterables, Strings } from '../system';
import { ViewsWithRepositoryFolders } from '../views/viewBase';
import { Commands } from './common'; import { Commands } from './common';
import { GitActions } from './gitCommands.actions'; import { GitActions } from './gitCommands.actions';
import { import {
@ -499,10 +500,7 @@ export async function* pickBranchStep<
: branches, : branches,
onDidClickItemButton: (quickpick, button, { item }) => { onDidClickItemButton: (quickpick, button, { item }) => {
if (button === QuickCommandButtons.RevealInSideBar) { if (button === QuickCommandButtons.RevealInSideBar) {
void GitActions.Branch.reveal(item, {
select: true,
expand: true,
});
void GitActions.Branch.reveal(item, { select: true, focus: false, expand: true });
} }
}, },
keys: ['right', 'alt+right', 'ctrl+right'], keys: ['right', 'alt+right', 'ctrl+right'],
@ -558,10 +556,7 @@ export async function* pickBranchesStep<
: branches, : branches,
onDidClickItemButton: (quickpick, button, { item }) => { onDidClickItemButton: (quickpick, button, { item }) => {
if (button === QuickCommandButtons.RevealInSideBar) { if (button === QuickCommandButtons.RevealInSideBar) {
void GitActions.Branch.reveal(item, {
select: true,
expand: true,
});
void GitActions.Branch.reveal(item, { select: true, focus: false, expand: true });
} }
}, },
keys: ['right', 'alt+right', 'ctrl+right'], keys: ['right', 'alt+right', 'ctrl+right'],
@ -644,11 +639,11 @@ export async function* pickBranchOrTagStep<
if (button === QuickCommandButtons.RevealInSideBar) { if (button === QuickCommandButtons.RevealInSideBar) {
if (GitReference.isBranch(item)) { if (GitReference.isBranch(item)) {
void GitActions.Branch.reveal(item, { select: true, expand: true });
void GitActions.Branch.reveal(item, { select: true, focus: false, expand: true });
} else if (GitReference.isTag(item)) { } else if (GitReference.isTag(item)) {
void GitActions.Tag.reveal(item, { select: true, expand: true });
void GitActions.Tag.reveal(item, { select: true, focus: false, expand: true });
} else if (GitReference.isRevision(item)) { } else if (GitReference.isRevision(item)) {
void GitActions.Commit.reveal(item, { select: true, expand: true });
void GitActions.Commit.reveal(item, { select: true, focus: false, expand: true });
} }
} }
return false; return false;
@ -753,11 +748,11 @@ export async function* pickBranchOrTagStepMultiRepo<
onDidClickItemButton: (quickpick, button, { item }) => { onDidClickItemButton: (quickpick, button, { item }) => {
if (button === QuickCommandButtons.RevealInSideBar) { if (button === QuickCommandButtons.RevealInSideBar) {
if (GitReference.isBranch(item)) { if (GitReference.isBranch(item)) {
void GitActions.Branch.reveal(item, { select: true, expand: true });
void GitActions.Branch.reveal(item, { select: true, focus: false, expand: true });
} else if (GitReference.isTag(item)) { } else if (GitReference.isTag(item)) {
void GitActions.Tag.reveal(item, { select: true, expand: true });
void GitActions.Tag.reveal(item, { select: true, focus: false, expand: true });
} else if (GitReference.isRevision(item)) { } else if (GitReference.isRevision(item)) {
void GitActions.Commit.reveal(item, { select: true, expand: true });
void GitActions.Commit.reveal(item, { select: true, focus: false, expand: true });
} }
} }
}, },
@ -1102,8 +1097,25 @@ export async function* pickContributorsStep<
placeholder: placeholder, placeholder: placeholder,
matchOnDescription: true, matchOnDescription: true,
items: (await Container.instance.git.getContributors(state.repo.path)).map(c => items: (await Container.instance.git.getContributors(state.repo.path)).map(c =>
ContributorQuickPickItem.create(c, message?.includes(c.toCoauthor())),
ContributorQuickPickItem.create(c, message?.includes(c.toCoauthor()), {
buttons: [QuickCommandButtons.RevealInSideBar],
}),
), ),
onDidClickItemButton: (quickpick, button, { item }) => {
if (button === QuickCommandButtons.RevealInSideBar) {
void GitActions.Contributor.reveal(item, { select: true, focus: false, expand: true });
}
},
keys: ['right', 'alt+right', 'ctrl+right'],
onDidPressKey: quickpick => {
if (quickpick.activeItems.length === 0) return;
void GitActions.Contributor.reveal(quickpick.activeItems[0].item, {
select: true,
focus: false,
expand: true,
});
},
}); });
const selection: StepSelection<typeof step> = yield step; const selection: StepSelection<typeof step> = yield step;
return QuickCommand.canPickStepContinue(step, state, selection) ? selection.map(i => i.item) : StepResult.Break; return QuickCommand.canPickStepContinue(step, state, selection) ? selection.map(i => i.item) : StepResult.Break;
@ -1111,7 +1123,7 @@ export async function* pickContributorsStep<
export async function* pickRepositoryStep< export async function* pickRepositoryStep<
State extends PartialStepState & { repo?: string | Repository }, State extends PartialStepState & { repo?: string | Repository },
Context extends { repos: Repository[]; title: string },
Context extends { repos: Repository[]; title: string; associatedView: ViewsWithRepositoryFolders },
>(state: State, context: Context, placeholder: string = 'Choose a repository'): AsyncStepResultGenerator<Repository> { >(state: State, context: Context, placeholder: string = 'Choose a repository'): AsyncStepResultGenerator<Repository> {
if (typeof state.repo === 'string') { if (typeof state.repo === 'string') {
state.repo = await Container.instance.git.getRepository(state.repo); state.repo = await Container.instance.git.getRepository(state.repo);
@ -1137,8 +1149,9 @@ export async function* pickRepositoryStep<
), ),
onDidClickItemButton: (quickpick, button, { item }) => { onDidClickItemButton: (quickpick, button, { item }) => {
if (button === QuickCommandButtons.RevealInSideBar) { if (button === QuickCommandButtons.RevealInSideBar) {
void Container.instance.repositoriesView.revealRepository(item.path, {
void GitActions.Repository.reveal(item.path, context.associatedView, {
select: true, select: true,
focus: false,
expand: true, expand: true,
}); });
} }
@ -1147,7 +1160,7 @@ export async function* pickRepositoryStep<
onDidPressKey: quickpick => { onDidPressKey: quickpick => {
if (quickpick.activeItems.length === 0) return; if (quickpick.activeItems.length === 0) return;
void Container.instance.repositoriesView.revealRepository(quickpick.activeItems[0].item.path, {
void GitActions.Repository.reveal(quickpick.activeItems[0].item.path, context.associatedView, {
select: true, select: true,
focus: false, focus: false,
expand: true, expand: true,
@ -1160,7 +1173,7 @@ export async function* pickRepositoryStep<
export async function* pickRepositoriesStep< export async function* pickRepositoriesStep<
State extends PartialStepState & { repos?: string[] | Repository[] }, State extends PartialStepState & { repos?: string[] | Repository[] },
Context extends { repos: Repository[]; title: string },
Context extends { repos: Repository[]; title: string; associatedView: ViewsWithRepositoryFolders },
>( >(
state: State, state: State,
context: Context, context: Context,
@ -1206,8 +1219,9 @@ export async function* pickRepositoriesStep<
), ),
onDidClickItemButton: (quickpick, button, { item }) => { onDidClickItemButton: (quickpick, button, { item }) => {
if (button === QuickCommandButtons.RevealInSideBar) { if (button === QuickCommandButtons.RevealInSideBar) {
void Container.instance.repositoriesView.revealRepository(item.path, {
void GitActions.Repository.reveal(item.path, context.associatedView, {
select: true, select: true,
focus: false,
expand: true, expand: true,
}); });
} }
@ -1216,7 +1230,7 @@ export async function* pickRepositoriesStep<
onDidPressKey: quickpick => { onDidPressKey: quickpick => {
if (quickpick.activeItems.length === 0) return; if (quickpick.activeItems.length === 0) return;
void Container.instance.repositoriesView.revealRepository(quickpick.activeItems[0].item.path, {
void GitActions.Repository.reveal(quickpick.activeItems[0].item.path, context.associatedView, {
select: true, select: true,
focus: false, focus: false,
expand: true, expand: true,
@ -1331,6 +1345,7 @@ export async function* pickTagsStep<
if (button === QuickCommandButtons.RevealInSideBar) { if (button === QuickCommandButtons.RevealInSideBar) {
void GitActions.Tag.reveal(item, { void GitActions.Tag.reveal(item, {
select: true, select: true,
focus: false,
expand: true, expand: true,
}); });
} }

+ 1
- 0
src/config.ts View File

@ -565,6 +565,7 @@ export interface ContributorsViewConfig {
enabled: boolean; enabled: boolean;
showForCommits: boolean; showForCommits: boolean;
}; };
reveal: boolean;
showAllBranches: boolean; showAllBranches: boolean;
showStatistics: boolean; showStatistics: boolean;
} }

+ 11
- 9
src/git/models/models.ts View File

@ -251,7 +251,7 @@ export namespace GitReference {
export function toString( export function toString(
refs: GitReference | GitReference[] | undefined, refs: GitReference | GitReference[] | undefined,
options?: { capitalize?: boolean; expand?: boolean; icon?: boolean; label?: boolean } | false,
options?: { capitalize?: boolean; expand?: boolean; icon?: boolean; label?: boolean; quoted?: boolean } | false,
) { ) {
if (refs == null) return ''; if (refs == null) return '';
@ -263,15 +263,16 @@ export namespace GitReference {
let result; let result;
if (!Array.isArray(refs) || refs.length === 1) { if (!Array.isArray(refs) || refs.length === 1) {
const ref = Array.isArray(refs) ? refs[0] : refs; const ref = Array.isArray(refs) ? refs[0] : refs;
let refName = options?.quoted ? `'${ref.name}'` : ref.name;
switch (ref.refType) { switch (ref.refType) {
case 'branch': case 'branch':
result = `${options.label ? `${ref.remote ? 'remote ' : ''}branch ` : ''}${ result = `${options.label ? `${ref.remote ? 'remote ' : ''}branch ` : ''}${
options.icon ? `$(git-branch)${GlyphChars.Space}${ref.name}${GlyphChars.Space}` : ref.name
options.icon ? `$(git-branch)${GlyphChars.Space}${refName}${GlyphChars.Space}` : refName
}`; }`;
break; break;
case 'tag': case 'tag':
result = `${options.label ? 'tag ' : ''}${ result = `${options.label ? 'tag ' : ''}${
options.icon ? `$(tag)${GlyphChars.Space}${ref.name}${GlyphChars.Space}` : ref.name
options.icon ? `$(tag)${GlyphChars.Space}${refName}${GlyphChars.Space}` : refName
}`; }`;
break; break;
default: { default: {
@ -291,7 +292,7 @@ export namespace GitReference {
: `${message ?? ref.number ?? ref.name}` : `${message ?? ref.number ?? ref.name}`
}`; }`;
} else if (GitRevision.isRange(ref.ref)) { } else if (GitRevision.isRange(ref.ref)) {
result = ref.name;
result = refName;
} else { } else {
let message; let message;
if (options.expand && ref.message) { if (options.expand && ref.message) {
@ -301,20 +302,21 @@ export namespace GitReference {
: ` (${ref.message})`; : ` (${ref.message})`;
} }
let name;
let prefix; let prefix;
if (options.expand && options.label && GitRevision.isShaParent(ref.ref)) { if (options.expand && options.label && GitRevision.isShaParent(ref.ref)) {
name = ref.name.endsWith('^') ? ref.name.substr(0, ref.name.length - 1) : ref.name;
refName = ref.name.endsWith('^') ? ref.name.substr(0, ref.name.length - 1) : ref.name;
if (options?.quoted) {
refName = `'${refName}'`;
}
prefix = 'before '; prefix = 'before ';
} else { } else {
name = ref.name;
prefix = ''; prefix = '';
} }
result = `${options.label ? `${prefix}commit ` : ''}${ result = `${options.label ? `${prefix}commit ` : ''}${
options.icon options.icon
? `$(git-commit)${GlyphChars.Space}${name}${message ?? ''}${GlyphChars.Space}`
: `${name}${message ?? ''}`
? `$(git-commit)${GlyphChars.Space}${refName}${message ?? ''}${GlyphChars.Space}`
: `${refName}${message ?? ''}`
}`; }`;
} }
break; break;

+ 5
- 4
src/quickpicks/gitQuickPickItems.ts View File

@ -42,8 +42,8 @@ export namespace BranchQuickPickItem {
options: { options: {
alwaysShow?: boolean; alwaysShow?: boolean;
buttons?: QuickInputButton[]; buttons?: QuickInputButton[];
current?: boolean | 'checkmark';
checked?: boolean; checked?: boolean;
current?: boolean | 'checkmark';
ref?: boolean; ref?: boolean;
status?: boolean; status?: boolean;
type?: boolean | 'remote'; type?: boolean | 'remote';
@ -225,12 +225,13 @@ export namespace ContributorQuickPickItem {
export function create( export function create(
contributor: GitContributor, contributor: GitContributor,
picked?: boolean, picked?: boolean,
options: { alwaysShow?: boolean } = {},
options: { alwaysShow?: boolean; buttons?: QuickInputButton[] } = {},
): ContributorQuickPickItem { ): ContributorQuickPickItem {
const item: ContributorQuickPickItem = { const item: ContributorQuickPickItem = {
label: contributor.name, label: contributor.name,
description: contributor.email, description: contributor.email,
alwaysShow: options.alwaysShow, alwaysShow: options.alwaysShow,
buttons: options.buttons,
picked: picked, picked: picked,
item: contributor, item: contributor,
}; };
@ -249,7 +250,7 @@ export namespace RefQuickPickItem {
ref: string | GitReference, ref: string | GitReference,
repoPath: string, repoPath: string,
picked?: boolean, picked?: boolean,
options: { alwaysShow?: boolean; buttons?: QuickInputButton[]; ref?: boolean; icon?: boolean } = {},
options: { alwaysShow?: boolean; buttons?: QuickInputButton[]; icon?: boolean; ref?: boolean } = {},
): RefQuickPickItem { ): RefQuickPickItem {
if (ref === '') { if (ref === '') {
return { return {
@ -399,8 +400,8 @@ export namespace TagQuickPickItem {
options: { options: {
alwaysShow?: boolean; alwaysShow?: boolean;
buttons?: QuickInputButton[]; buttons?: QuickInputButton[];
message?: boolean;
checked?: boolean; checked?: boolean;
message?: boolean;
ref?: boolean; ref?: boolean;
type?: boolean; type?: boolean;
} = {}, } = {},

+ 24
- 3
src/views/branchesView.ts View File

@ -120,7 +120,11 @@ export class BranchesView extends ViewBase
super('gitlens.views.branches', 'Branches', container); super('gitlens.views.branches', 'Branches', container);
} }
getRoot() {
override get canReveal(): boolean {
return this.config.reveal || !configuration.get('views.repositories.showBranches');
}
protected getRoot() {
return new BranchesViewNode(this); return new BranchesViewNode(this);
} }
@ -278,7 +282,7 @@ export class BranchesView extends ViewBase
return window.withProgress( return window.withProgress(
{ {
location: ProgressLocation.Notification, location: ProgressLocation.Notification,
title: `Revealing ${GitReference.toString(branch, { icon: false })} in the side bar...`,
title: `Revealing ${GitReference.toString(branch, { icon: false, quoted: true })} in the side bar...`,
cancellable: true, cancellable: true,
}, },
async (progress, token) => { async (progress, token) => {
@ -304,7 +308,7 @@ export class BranchesView extends ViewBase
return window.withProgress( return window.withProgress(
{ {
location: ProgressLocation.Notification, location: ProgressLocation.Notification,
title: `Revealing ${GitReference.toString(commit, { icon: false })} in the side bar...`,
title: `Revealing ${GitReference.toString(commit, { icon: false, quoted: true })} in the side bar...`,
cancellable: true, cancellable: true,
}, },
async (progress, token) => { async (progress, token) => {
@ -318,6 +322,23 @@ export class BranchesView extends ViewBase
); );
} }
@gate(() => '')
async revealRepository(
repoPath: string,
options?: { select?: boolean; focus?: boolean; expand?: boolean | number },
) {
const node = await this.findNode(RepositoryFolderNode.getId(repoPath), {
maxDepth: 1,
canTraverse: n => n instanceof BranchesViewNode || n instanceof RepositoryFolderNode,
});
if (node !== undefined) {
await this.reveal(node, options);
}
return node;
}
private setLayout(layout: ViewBranchesLayout) { private setLayout(layout: ViewBranchesLayout) {
return configuration.updateEffective(`views.${this.configKey}.branches.layout` as const, layout); return configuration.updateEffective(`views.${this.configKey}.branches.layout` as const, layout);
} }

+ 23
- 2
src/views/commitsView.ts View File

@ -183,12 +183,16 @@ export class CommitsView extends ViewBase {
super('gitlens.views.commits', 'Commits', container); super('gitlens.views.commits', 'Commits', container);
} }
override get canReveal(): boolean {
return this.config.reveal || !configuration.get('views.repositories.showCommits');
}
private readonly _state: CommitsViewState = {}; private readonly _state: CommitsViewState = {};
get state(): CommitsViewState { get state(): CommitsViewState {
return this._state; return this._state;
} }
getRoot() {
protected getRoot() {
return new CommitsViewNode(this); return new CommitsViewNode(this);
} }
@ -343,7 +347,7 @@ export class CommitsView extends ViewBase {
return window.withProgress( return window.withProgress(
{ {
location: ProgressLocation.Notification, location: ProgressLocation.Notification,
title: `Revealing ${GitReference.toString(commit, { icon: false })} in the side bar...`,
title: `Revealing ${GitReference.toString(commit, { icon: false, quoted: true })} in the side bar...`,
cancellable: true, cancellable: true,
}, },
async (progress, token) => { async (progress, token) => {
@ -357,6 +361,23 @@ export class CommitsView extends ViewBase {
); );
} }
@gate(() => '')
async revealRepository(
repoPath: string,
options?: { select?: boolean; focus?: boolean; expand?: boolean | number },
) {
const node = await this.findNode(RepositoryFolderNode.getId(repoPath), {
maxDepth: 1,
canTraverse: n => n instanceof CommitsViewNode || n instanceof RepositoryFolderNode,
});
if (node !== undefined) {
await this.reveal(node, options);
}
return node;
}
private setFilesLayout(layout: ViewFilesLayout) { private setFilesLayout(layout: ViewFilesLayout) {
return configuration.updateEffective(`views.${this.configKey}.files.layout` as const, layout); return configuration.updateEffective(`views.${this.configKey}.files.layout` as const, layout);
} }

+ 86
- 5
src/views/contributorsView.ts View File

@ -1,13 +1,29 @@
'use strict'; 'use strict';
import { commands, ConfigurationChangeEvent, Disposable, TreeItem, TreeItemCollapsibleState } from 'vscode';
import {
CancellationToken,
commands,
ConfigurationChangeEvent,
Disposable,
ProgressLocation,
TreeItem,
TreeItemCollapsibleState,
window,
} from 'vscode';
import { Avatars } from '../avatars'; import { Avatars } from '../avatars';
import { configuration, ContributorsViewConfig, ViewFilesLayout } from '../configuration'; import { configuration, ContributorsViewConfig, ViewFilesLayout } from '../configuration';
import { GlyphChars } from '../constants'; import { GlyphChars } from '../constants';
import { Container } from '../container'; import { Container } from '../container';
import { RepositoryChange, RepositoryChangeComparisonMode, RepositoryChangeEvent } from '../git/git';
import { GitContributor, RepositoryChange, RepositoryChangeComparisonMode, RepositoryChangeEvent } from '../git/git';
import { GitUri } from '../git/gitUri'; import { GitUri } from '../git/gitUri';
import { debug, Strings } from '../system';
import { ContributorsNode, RepositoriesSubscribeableNode, RepositoryFolderNode, ViewNode } from './nodes';
import { debug, gate, Strings } from '../system';
import {
ContributorNode,
ContributorsNode,
RepositoriesSubscribeableNode,
RepositoryFolderNode,
RepositoryNode,
ViewNode,
} from './nodes';
import { ViewBase } from './viewBase'; import { ViewBase } from './viewBase';
export class ContributorsRepositoryNode extends RepositoryFolderNode<ContributorsView, ContributorsNode> { export class ContributorsRepositoryNode extends RepositoryFolderNode<ContributorsView, ContributorsNode> {
@ -110,7 +126,11 @@ export class ContributorsView extends ViewBase
super('gitlens.views.contributors', 'Contributors', container); super('gitlens.views.contributors', 'Contributors', container);
} }
getRoot() {
override get canReveal(): boolean {
return this.config.reveal || !configuration.get('views.repositories.showContributors');
}
protected getRoot() {
return new ContributorsViewNode(this); return new ContributorsViewNode(this);
} }
@ -200,6 +220,67 @@ export class ContributorsView extends ViewBase
return true; return true;
} }
findContributor(contributor: GitContributor, token?: CancellationToken) {
const repoNodeId = RepositoryNode.getId(contributor.repoPath);
return this.findNode(ContributorNode.getId(contributor.repoPath, contributor.name, contributor.email), {
maxDepth: 2,
canTraverse: n => {
if (n instanceof ContributorsViewNode) return true;
if (n instanceof ContributorsRepositoryNode) {
return n.id.startsWith(repoNodeId);
}
return false;
},
token: token,
});
}
@gate(() => '')
async revealRepository(
repoPath: string,
options?: { select?: boolean; focus?: boolean; expand?: boolean | number },
) {
const node = await this.findNode(RepositoryFolderNode.getId(repoPath), {
maxDepth: 1,
canTraverse: n => n instanceof ContributorsViewNode || n instanceof RepositoryFolderNode,
});
if (node !== undefined) {
await this.reveal(node, options);
}
return node;
}
@gate(() => '')
async revealContributor(
contributor: GitContributor,
options?: {
select?: boolean;
focus?: boolean;
expand?: boolean | number;
},
) {
return window.withProgress(
{
location: ProgressLocation.Notification,
title: `Revealing contributor '${contributor.name}' in the side bar...`,
cancellable: true,
},
async (progress, token) => {
const node = await this.findContributor(contributor, token);
if (node == null) return undefined;
await this.ensureRevealNode(node, options);
return node;
},
);
}
private setFilesLayout(layout: ViewFilesLayout) { private setFilesLayout(layout: ViewFilesLayout) {
return configuration.updateEffective(`views.${this.configKey}.files.layout` as const, layout); return configuration.updateEffective(`views.${this.configKey}.files.layout` as const, layout);
} }

+ 1
- 1
src/views/lineHistoryView.ts View File

@ -21,7 +21,7 @@ export class LineHistoryView extends ViewBase
return false; return false;
} }
getRoot() {
protected getRoot() {
return new LineHistoryTrackerNode(this); return new LineHistoryTrackerNode(this);
} }

+ 25
- 4
src/views/remotesView.ts View File

@ -114,7 +114,11 @@ export class RemotesView extends ViewBase {
super('gitlens.views.remotes', 'Remotes', container); super('gitlens.views.remotes', 'Remotes', container);
} }
getRoot() {
override get canReveal(): boolean {
return this.config.reveal || !configuration.get('views.repositories.showRemotes');
}
protected getRoot() {
return new RemotesViewNode(this); return new RemotesViewNode(this);
} }
@ -297,7 +301,7 @@ export class RemotesView extends ViewBase {
return window.withProgress( return window.withProgress(
{ {
location: ProgressLocation.Notification, location: ProgressLocation.Notification,
title: `Revealing ${GitReference.toString(branch, { icon: false })} in the side bar...`,
title: `Revealing ${GitReference.toString(branch, { icon: false, quoted: true })} in the side bar...`,
cancellable: true, cancellable: true,
}, },
async (progress, token) => { async (progress, token) => {
@ -323,7 +327,7 @@ export class RemotesView extends ViewBase {
return window.withProgress( return window.withProgress(
{ {
location: ProgressLocation.Notification, location: ProgressLocation.Notification,
title: `Revealing ${GitReference.toString(commit, { icon: false })} in the side bar...`,
title: `Revealing ${GitReference.toString(commit, { icon: false, quoted: true })} in the side bar...`,
cancellable: true, cancellable: true,
}, },
async (progress, token) => { async (progress, token) => {
@ -349,7 +353,7 @@ export class RemotesView extends ViewBase {
return window.withProgress( return window.withProgress(
{ {
location: ProgressLocation.Notification, location: ProgressLocation.Notification,
title: `Revealing remote ${remote.name} in the side bar...`,
title: `Revealing remote '${remote.name}' in the side bar...`,
cancellable: true, cancellable: true,
}, },
async (progress, token) => { async (progress, token) => {
@ -363,6 +367,23 @@ export class RemotesView extends ViewBase {
); );
} }
@gate(() => '')
async revealRepository(
repoPath: string,
options?: { select?: boolean; focus?: boolean; expand?: boolean | number },
) {
const node = await this.findNode(RepositoryFolderNode.getId(repoPath), {
maxDepth: 1,
canTraverse: n => n instanceof RemotesViewNode || n instanceof RepositoryFolderNode,
});
if (node !== undefined) {
await this.reveal(node, options);
}
return node;
}
private setLayout(layout: ViewBranchesLayout) { private setLayout(layout: ViewBranchesLayout) {
return configuration.updateEffective(`views.${this.configKey}.branches.layout` as const, layout); return configuration.updateEffective(`views.${this.configKey}.branches.layout` as const, layout);
} }

+ 107
- 16
src/views/repositoriesView.ts View File

@ -21,8 +21,10 @@ import { Container } from '../container';
import { import {
GitBranch, GitBranch,
GitBranchReference, GitBranchReference,
GitContributor,
GitLogCommit, GitLogCommit,
GitReference, GitReference,
GitRemote,
GitRevisionReference, GitRevisionReference,
GitStashReference, GitStashReference,
GitTagReference, GitTagReference,
@ -34,6 +36,7 @@ import {
BranchOrTagFolderNode, BranchOrTagFolderNode,
BranchTrackingStatusNode, BranchTrackingStatusNode,
CompareBranchNode, CompareBranchNode,
ContributorNode,
ContributorsNode, ContributorsNode,
ReflogNode, ReflogNode,
RemoteNode, RemoteNode,
@ -58,7 +61,7 @@ export class RepositoriesView extends ViewBase
return this._onDidChangeAutoRefresh.event; return this._onDidChangeAutoRefresh.event;
} }
getRoot() {
protected getRoot() {
return new RepositoriesNode(this); return new RepositoriesNode(this);
} }
@ -368,7 +371,7 @@ export class RepositoriesView extends ViewBase
allowPaging: true, allowPaging: true,
maxDepth: 8, maxDepth: 8,
canTraverse: n => { canTraverse: n => {
// Only search for commit nodes in the same repo within BranchNodes
// Only search for commit nodes in the same repo within BranchNode/RemoteNode
if (n instanceof RepositoriesNode) return true; if (n instanceof RepositoriesNode) return true;
if (n instanceof RemoteNode) { if (n instanceof RemoteNode) {
@ -389,6 +392,45 @@ export class RepositoriesView extends ViewBase
}); });
} }
findContributor(contributor: GitContributor, token?: CancellationToken) {
const repoNodeId = RepositoryNode.getId(contributor.repoPath);
return this.findNode(ContributorNode.getId(contributor.repoPath, contributor.name, contributor.email), {
maxDepth: 2,
canTraverse: n => {
// Only search for contributor nodes in the same repo within a ContributorsNode
if (n instanceof RepositoriesNode) return true;
if (n instanceof RepositoryNode || n instanceof ContributorsNode) {
return n.id.startsWith(repoNodeId);
}
return false;
},
token: token,
});
}
findRemote(remote: GitRemote, token?: CancellationToken) {
const repoNodeId = RepositoryNode.getId(remote.repoPath);
return this.findNode((n: any) => n.remote?.name === remote.name, {
allowPaging: true,
maxDepth: 2,
canTraverse: n => {
// Only search for remote nodes in the same repo within a RemotesNode
if (n instanceof RepositoriesNode) return true;
if (n instanceof RepositoryNode || n instanceof RemotesNode) {
return n.id.startsWith(repoNodeId);
}
return false;
},
token: token,
});
}
findStash(stash: GitStashReference, token?: CancellationToken) { findStash(stash: GitStashReference, token?: CancellationToken) {
const repoNodeId = RepositoryNode.getId(stash.repoPath); const repoNodeId = RepositoryNode.getId(stash.repoPath);
@ -440,7 +482,10 @@ export class RepositoriesView extends ViewBase
return window.withProgress( return window.withProgress(
{ {
location: ProgressLocation.Notification, location: ProgressLocation.Notification,
title: `Revealing ${GitReference.toString(branch, { icon: false })} in the Repositories view...`,
title: `Revealing ${GitReference.toString(branch, {
icon: false,
quoted: true,
})} in the Repositories view...`,
cancellable: true, cancellable: true,
}, },
async (progress, token) => { async (progress, token) => {
@ -498,7 +543,10 @@ export class RepositoriesView extends ViewBase
return window.withProgress( return window.withProgress(
{ {
location: ProgressLocation.Notification, location: ProgressLocation.Notification,
title: `Revealing ${GitReference.toString(commit, { icon: false })} in the Repositories view...`,
title: `Revealing ${GitReference.toString(commit, {
icon: false,
quoted: true,
})} in the Repositories view...`,
cancellable: true, cancellable: true,
}, },
async (progress, token) => { async (progress, token) => {
@ -513,6 +561,58 @@ export class RepositoriesView extends ViewBase
} }
@gate(() => '') @gate(() => '')
async revealContributor(
contributor: GitContributor,
options?: {
select?: boolean;
focus?: boolean;
expand?: boolean | number;
},
) {
return window.withProgress(
{
location: ProgressLocation.Notification,
title: `Revealing contributor '${contributor.name} in the Repositories view...`,
cancellable: true,
},
async (progress, token) => {
const node = await this.findContributor(contributor, token);
if (node == null) return undefined;
await this.ensureRevealNode(node, options);
return node;
},
);
}
@gate(() => '')
revealRemote(
remote: GitRemote,
options?: {
select?: boolean;
focus?: boolean;
expand?: boolean | number;
},
) {
return window.withProgress(
{
location: ProgressLocation.Notification,
title: `Revealing remote '${remote.name}' in the side bar...`,
cancellable: true,
},
async (progress, token) => {
const node = await this.findRemote(remote, token);
if (node == null) return undefined;
await this.ensureRevealNode(node, options);
return node;
},
);
}
@gate(() => '')
async revealRepository( async revealRepository(
repoPath: string, repoPath: string,
options?: { options?: {
@ -525,16 +625,7 @@ export class RepositoriesView extends ViewBase
const node = await this.findNode(repoNodeId, { const node = await this.findNode(repoNodeId, {
maxDepth: 1, maxDepth: 1,
canTraverse: n => {
// Only search for branches nodes in the same repo
if (n instanceof RepositoriesNode) return true;
// if (n instanceof RepositoryNode) {
// return n.id.startsWith(repoNodeId);
// }
return false;
},
canTraverse: n => n instanceof RepositoriesNode,
}); });
if (node !== undefined) { if (node !== undefined) {
@ -556,7 +647,7 @@ export class RepositoriesView extends ViewBase
return window.withProgress( return window.withProgress(
{ {
location: ProgressLocation.Notification, location: ProgressLocation.Notification,
title: `Revealing ${GitReference.toString(stash, { icon: false })} in the Repositories view...`,
title: `Revealing ${GitReference.toString(stash, { icon: false, quoted: true })} in the Repositories view...`,
cancellable: true, cancellable: true,
}, },
async (progress, token) => { async (progress, token) => {
@ -614,7 +705,7 @@ export class RepositoriesView extends ViewBase
return window.withProgress( return window.withProgress(
{ {
location: ProgressLocation.Notification, location: ProgressLocation.Notification,
title: `Revealing ${GitReference.toString(tag, { icon: false })} in the Repositories view...`,
title: `Revealing ${GitReference.toString(tag, { icon: false, quoted: true })} in the Repositories view...`,
cancellable: true, cancellable: true,
}, },
async (progress, token) => { async (progress, token) => {

+ 19
- 1
src/views/searchAndCompareView.ts View File

@ -10,6 +10,7 @@ import { debug, gate, Iterables, log, Promises } from '../system';
import { import {
CompareResultsNode, CompareResultsNode,
ContextValues, ContextValues,
RepositoryFolderNode,
ResultsFilesNode, ResultsFilesNode,
SearchResultsNode, SearchResultsNode,
unknownGitUri, unknownGitUri,
@ -258,7 +259,7 @@ export class SearchAndCompareView extends ViewBase
void setContext(ContextKeys.ViewsSearchAndCompareKeepResults, this.keepResults); void setContext(ContextKeys.ViewsSearchAndCompareKeepResults, this.keepResults);
} }
getRoot() {
protected getRoot() {
return new SearchAndCompareViewNode(this); return new SearchAndCompareViewNode(this);
} }
@ -497,6 +498,23 @@ export class SearchAndCompareView extends ViewBase
this.triggerNodeChange(this.ensureRoot()); this.triggerNodeChange(this.ensureRoot());
} }
@gate(() => '')
async revealRepository(
repoPath: string,
options?: { select?: boolean; focus?: boolean; expand?: boolean | number },
) {
const node = await this.findNode(RepositoryFolderNode.getId(repoPath), {
maxDepth: 1,
canTraverse: n => n instanceof SearchAndCompareViewNode || n instanceof RepositoryFolderNode,
});
if (node !== undefined) {
await this.reveal(node, options);
}
return node;
}
private async addResults( private async addResults(
results: CompareResultsNode | SearchResultsNode, results: CompareResultsNode | SearchResultsNode,
options: { options: {

+ 23
- 2
src/views/stashesView.ts View File

@ -102,7 +102,11 @@ export class StashesView extends ViewBase {
super('gitlens.views.stashes', 'Stashes', container); super('gitlens.views.stashes', 'Stashes', container);
} }
getRoot() {
override get canReveal(): boolean {
return this.config.reveal || !configuration.get('views.repositories.showStashes');
}
protected getRoot() {
return new StashesViewNode(this); return new StashesViewNode(this);
} }
@ -177,6 +181,23 @@ export class StashesView extends ViewBase {
} }
@gate(() => '') @gate(() => '')
async revealRepository(
repoPath: string,
options?: { select?: boolean; focus?: boolean; expand?: boolean | number },
) {
const node = await this.findNode(RepositoryFolderNode.getId(repoPath), {
maxDepth: 1,
canTraverse: n => n instanceof StashesViewNode || n instanceof RepositoryFolderNode,
});
if (node !== undefined) {
await this.reveal(node, options);
}
return node;
}
@gate(() => '')
async revealStash( async revealStash(
stash: GitStashReference, stash: GitStashReference,
options?: { options?: {
@ -188,7 +209,7 @@ export class StashesView extends ViewBase {
return window.withProgress( return window.withProgress(
{ {
location: ProgressLocation.Notification, location: ProgressLocation.Notification,
title: `Revealing ${GitReference.toString(stash, { icon: false })} in the side bar...`,
title: `Revealing ${GitReference.toString(stash, { icon: false, quoted: true })} in the side bar...`,
cancellable: true, cancellable: true,
}, },
async (progress, token) => { async (progress, token) => {

+ 23
- 2
src/views/tagsView.ts View File

@ -102,7 +102,11 @@ export class TagsView extends ViewBase {
super('gitlens.views.tags', 'Tags', container); super('gitlens.views.tags', 'Tags', container);
} }
getRoot() {
override get canReveal(): boolean {
return this.config.reveal || !configuration.get('views.repositories.showTags');
}
protected getRoot() {
return new TagsViewNode(this); return new TagsViewNode(this);
} }
@ -199,6 +203,23 @@ export class TagsView extends ViewBase {
} }
@gate(() => '') @gate(() => '')
async revealRepository(
repoPath: string,
options?: { select?: boolean; focus?: boolean; expand?: boolean | number },
) {
const node = await this.findNode(RepositoryFolderNode.getId(repoPath), {
maxDepth: 1,
canTraverse: n => n instanceof TagsViewNode || n instanceof RepositoryFolderNode,
});
if (node !== undefined) {
await this.reveal(node, options);
}
return node;
}
@gate(() => '')
revealTag( revealTag(
tag: GitTagReference, tag: GitTagReference,
options?: { options?: {
@ -210,7 +231,7 @@ export class TagsView extends ViewBase {
return window.withProgress( return window.withProgress(
{ {
location: ProgressLocation.Notification, location: ProgressLocation.Notification,
title: `Revealing ${GitReference.toString(tag, { icon: false })} in the side bar...`,
title: `Revealing ${GitReference.toString(tag, { icon: false, quoted: true })} in the side bar...`,
cancellable: true, cancellable: true,
}, },
async (progress, token) => { async (progress, token) => {

+ 7
- 2
src/views/viewBase.ts View File

@ -59,6 +59,7 @@ export type View =
| StashesView | StashesView
| TagsView; | TagsView;
export type ViewsWithCommits = Exclude<View, FileHistoryView | LineHistoryView | StashesView>; export type ViewsWithCommits = Exclude<View, FileHistoryView | LineHistoryView | StashesView>;
export type ViewsWithRepositoryFolders = Exclude<View, RepositoriesView | FileHistoryView | LineHistoryView>;
export interface TreeViewNodeCollapsibleStateChangeEvent<T> extends TreeViewExpansionEvent<T> { export interface TreeViewNodeCollapsibleStateChangeEvent<T> extends TreeViewExpansionEvent<T> {
state: TreeItemCollapsibleState; state: TreeItemCollapsibleState;
@ -163,6 +164,10 @@ export abstract class ViewBase<
queueMicrotask(() => this.onConfigurationChanged()); queueMicrotask(() => this.onConfigurationChanged());
} }
get canReveal(): boolean {
return true;
}
protected get showCollapseAll(): boolean { protected get showCollapseAll(): boolean {
return true; return true;
} }
@ -353,8 +358,8 @@ export abstract class ViewBase<
// If we have no root (e.g. never been initialized) force it so the tree will load properly // If we have no root (e.g. never been initialized) force it so the tree will load properly
await this.show({ preserveFocus: true }); await this.show({ preserveFocus: true });
// Since we have to show the view, let the callstack unwind before we try to find the node
return new Promise<ViewNode | undefined>(resolve => queueMicrotask(() => resolve(find.call(this))));
// Since we have to show the view, give the view time to load and let the callstack unwind before we try to find the node
return new Promise<ViewNode | undefined>(resolve => setTimeout(() => resolve(find.call(this)), 100));
} }
private async findNodeCoreBFS( private async findNodeCoreBFS(

Loading…
Cancel
Save