Browse Source

Adds branch comparisons to worktrees

Adds associated PRs to worktree branches
Adds worktrees to the settings page
Adds unpublished markers to worktrees
main
Eric Amodio 2 years ago
parent
commit
1adc4be687
10 changed files with 500 additions and 60 deletions
  1. +24
    -8
      README.md
  2. +108
    -19
      package.json
  3. +2
    -0
      src/config.ts
  4. +13
    -0
      src/git/models/worktree.ts
  5. +2
    -2
      src/views/nodes/branchNode.ts
  6. +3
    -2
      src/views/nodes/compareBranchNode.ts
  7. +114
    -28
      src/views/nodes/worktreeNode.ts
  8. +33
    -1
      src/views/worktreesView.ts
  9. +190
    -0
      src/webviews/apps/settings/partials/views.worktrees.html
  10. +11
    -0
      src/webviews/apps/settings/settings.html

+ 24
- 8
README.md View File

@ -767,8 +767,8 @@ See also [View Settings](#view-settings- 'Jump to the View settings')
| `gitlens.views.commits.files.layout` | Specifies how the _Commits_ view will display files<br /><br />`auto` - automatically switches between displaying files as a `tree` or `list` based on the `gitlens.views.commits.files.threshold` value and the number of files at each nesting level<br />`list` - displays files as a list<br />`tree` - displays files as a tree |
| `gitlens.views.commits.files.threshold` | Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the _Commits_ view<br />Only applies when `gitlens.views.commits.files.layout` is set to `auto` |
| `gitlens.views.commits.pullRequests.enabled` | Specifies whether to query for pull requests associated with the current branch and commits in the _Commits_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.commits.pullRequests.showForBranches` | Specifies whether to query for pull requests associated with the current branch and commits in the _Commits_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.commits.pullRequests.showForCommits` | Specifies whether to show pull requests (if any) associated with the current branch in the _Commits_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.commits.pullRequests.showForBranches` | Specifies whether to query for pull requests associated with the current branch in the _Commits_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.commits.pullRequests.showForCommits` | Specifies whether to show pull requests (if any) associated with commits in the _Commits_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.commits.reveal` | Specifies whether to reveal commits in the _Commits_ view, otherwise they will be revealed in the _Repositories_ view |
| `gitlens.views.commits.showBranchComparison` | Specifies whether to show a comparison of the current branch or the working tree with a user-selected reference (branch, tag. etc) in the _Commits_ view<br /><br />`false` - hides the branch comparison<br />`branch` - compares the current branch with a user-selected reference<br />`working` - compares the working tree with a user-selected reference |
@ -825,9 +825,9 @@ See also [View Settings](#view-settings- 'Jump to the View settings')
| `gitlens.views.branches.files.compact` | Specifies whether to compact (flatten) unnecessary file nesting in the _Branches_ view.<br />Only applies when `gitlens.views.commits.files.layout` is set to `tree` or `auto` |
| `gitlens.views.branches.files.layout` | Specifies how the _Branches_ view will display files<br /><br />`auto` - automatically switches between displaying files as a `tree` or `list` based on the `gitlens.views.commits.files.threshold` value and the number of files at each nesting level<br />`list` - displays files as a list<br />`tree` - displays files as a tree |
| `gitlens.views.branches.files.threshold` | Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the _Branches_ view<br />Only applies when `gitlens.views.commits.files.layout` is set to `auto` |
| `gitlens.views.branches.pullRequests.enabled` | Specifies whether to query for pull requests associated with the current branch and commits in the _Branches_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.branches.pullRequests.showForBranches` | Specifies whether to query for pull requests associated with the current branch and commits in the _Branches_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.branches.pullRequests.showForCommits` | Specifies whether to show pull requests (if any) associated with the current branch in the _Branches_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.branches.pullRequests.enabled` | Specifies whether to query for pull requests associated with each branch and commits in the _Branches_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.branches.pullRequests.showForBranches` | Specifies whether to query for pull requests associated with each branch in the _Branches_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.branches.pullRequests.showForCommits` | Specifies whether to show pull requests (if any) associated with commits in the _Branches_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.branches.reveal` | Specifies whether to reveal branches in the _Branches_ view, otherwise they will be revealed in the _Repositories_ view |
| `gitlens.views.branches.showBranchComparison` | Specifies whether to show a comparison of the branch with a user-selected reference (branch, tag. etc) in the _Branches_ view<br /><br />`false` - hides the branch comparison<br />`branch` - compares the current branch with a user-selected reference |
@ -842,9 +842,9 @@ See also [View Settings](#view-settings- 'Jump to the View settings')
| `gitlens.views.remotes.files.compact` | Specifies whether to compact (flatten) unnecessary file nesting in the _Remotes_ view.<br />Only applies when `gitlens.views.commits.files.layout` is set to `tree` or `auto` |
| `gitlens.views.remotes.files.layout` | Specifies how the _Remotes_ view will display files<br /><br />`auto` - automatically switches between displaying files as a `tree` or `list` based on the `gitlens.views.commits.files.threshold` value and the number of files at each nesting level<br />`list` - displays files as a list<br />`tree` - displays files as a tree |
| `gitlens.views.remotes.files.threshold` | Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the _Remotes_ view<br />Only applies when `gitlens.views.commits.files.layout` is set to `auto` |
| `gitlens.views.remotes.pullRequests.enabled` | Specifies whether to query for pull requests associated with the current branch and commits in the _Remotes_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.remotes.pullRequests.showForBranches` | Specifies whether to query for pull requests associated with the current branch and commits in the _Remotes_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.remotes.pullRequests.showForCommits` | Specifies whether to show pull requests (if any) associated with the current branch in the _Remotes_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.remotes.pullRequests.enabled` | Specifies whether to query for pull requests associated with each branch and commits in the _Remotes_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.remotes.pullRequests.showForBranches` | Specifies whether to query for pull requests associated with each branch in the _Remotes_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.remotes.pullRequests.showForCommits` | Specifies whether to show pull requests (if any) associated with commits in the _Remotes_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.remotes.reveal` | Specifies whether to reveal remotes in the _Remotes_ view, otherwise they will be revealed in the _Repositories_ view |
| `gitlens.views.remotes.showBranchComparison` | Specifies whether to show a comparison of the branch with a user-selected reference (branch, tag. etc) in the _Remotes_ view<br /><br />`false` - hides the branch comparison<br />`branch` - compares the current branch with a user-selected reference |
@ -872,6 +872,22 @@ See also [View Settings](#view-settings- 'Jump to the View settings')
| `gitlens.views.tags.files.threshold` | Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the _Tags_ view<br />Only applies when `gitlens.views.commits.files.layout` is set to `auto` |
| `gitlens.views.tags.reveal` | Specifies whether to reveal tags in the _Tags_ view, otherwise they will be revealed in the _Repositories_ view |
## Worktrees View Settings [#](#worktrees-view-settings- 'Worktrees View Settings')
See also [View Settings](#view-settings- 'Jump to the View settings')
| Name | Description |
| ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `gitlens.views.worktrees.avatars` | Specifies whether to show avatar images instead of commit (or status) icons in the _Worktrees_ view |
| `gitlens.views.worktrees.files.compact` | Specifies whether to compact (flatten) unnecessary file nesting in the _Worktrees_ view.<br />Only applies when `gitlens.views.commits.files.layout` is set to `tree` or `auto` |
| `gitlens.views.worktrees.files.layout` | Specifies how the _Worktrees_ view will display files<br /><br />`auto` - automatically switches between displaying files as a `tree` or `list` based on the `gitlens.views.commits.files.threshold` value and the number of files at each nesting level<br />`list` - displays files as a list<br />`tree` - displays files as a tree |
| `gitlens.views.worktrees.files.threshold` | Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the _Worktrees_ view<br />Only applies when `gitlens.views.commits.files.layout` is set to `auto` |
| `gitlens.views.worktrees.pullRequests.enabled` | Specifies whether to query for pull requests associated with the worktree branch and commits in the _Worktrees_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.worktrees.pullRequests.showForBranches` | Specifies whether to query for pull requests associated with the worktree branch in the _Worktrees_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.worktrees.pullRequests.showForCommits` | Specifies whether to show pull requests (if any) associated with commits in the _Worktrees_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.worktrees.reveal` | Specifies whether to reveal worktrees in the _Worktrees_ view, otherwise they will be revealed in the _Repositories_ view |
| `gitlens.views.worktrees.showBranchComparison` | Specifies whether to show a comparison of the worktree branch with a user-selected reference (branch, tag. etc) in the _Worktrees_ view<br /><br />`false` - hides the branch comparison<br />`branch` - compares the current branch with a user-selected reference |
## Contributors View Settings [#](#contributors-view-settings- 'Contributors View Settings')
See also [View Settings](#view-settings- 'Jump to the View settings')

+ 108
- 19
package.json View File

@ -1236,14 +1236,14 @@
"gitlens.views.branches.pullRequests.enabled": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to query for pull requests associated with branches and commits in the _Branches_ view. Requires a connection to a supported remote service (e.g. GitHub)",
"markdownDescription": "Specifies whether to query for pull requests associated with each branch and commits in the _Branches_ view. Requires a connection to a supported remote service (e.g. GitHub)",
"scope": "window",
"order": 20
},
"gitlens.views.branches.pullRequests.showForBranches": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to show pull requests (if any) associated with branches in the _Branches_ view. Requires a connection to a supported remote service (e.g. GitHub)",
"markdownDescription": "Specifies whether to show pull requests (if any) associated with each branch in the _Branches_ view. Requires a connection to a supported remote service (e.g. GitHub)",
"scope": "window",
"order": 21
},
@ -1343,14 +1343,14 @@
"gitlens.views.remotes.pullRequests.enabled": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to query for pull requests associated with branches and commits in the _Remotes_ view. Requires a connection to a supported remote service (e.g. GitHub)",
"markdownDescription": "Specifies whether to query for pull requests associated with each branch and commits in the _Remotes_ view. Requires a connection to a supported remote service (e.g. GitHub)",
"scope": "window",
"order": 10
},
"gitlens.views.remotes.pullRequests.showForBranches": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to show pull requests (if any) associated with branches in the _Remotes_ view. Requires a connection to a supported remote service (e.g. GitHub)",
"markdownDescription": "Specifies whether to show pull requests (if any) associated with each branch in the _Remotes_ view. Requires a connection to a supported remote service (e.g. GitHub)",
"scope": "window",
"order": 11
},
@ -1559,29 +1559,58 @@
"title": "Worktrees View",
"order": 29,
"properties": {
"gitlens.worktrees.promptForLocation": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to prompt for a path when creating new worktrees",
"scope": "resource",
"order": 10
},
"gitlens.worktrees.defaultLocation": {
"type": "string",
"default": null,
"markdownDescription": "Specifies the default path in which new worktrees will be created",
"scope": "resource"
"scope": "resource",
"order": 11
},
"gitlens.worktrees.promptForLocation": {
"gitlens.views.worktrees.showBranchComparison": {
"type": [
"boolean",
"string"
],
"enum": [
false,
"branch"
],
"enumDescriptions": [
"Hides the branch comparison",
"Compares the worktree branch with a user-selected reference"
],
"default": "working",
"markdownDescription": "Specifies whether to show a comparison of the worktree branch with a user-selected reference (branch, tag. etc) in the _Worktrees_ view",
"scope": "window",
"order": 20
},
"gitlens.views.worktrees.pullRequests.enabled": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to prompt for a path when creating new worktrees",
"scope": "resource"
"markdownDescription": "Specifies whether to query for pull requests associated with the worktree branch and commits in the _Worktrees_ view. Requires a connection to a supported remote service (e.g. GitHub)",
"scope": "window",
"order": 30
},
"gitlens.views.worktrees.pullRequests.enabled": {
"gitlens.views.worktrees.pullRequests.showForBranches": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to query for pull requests associated with branches and commits in the _Worktrees_ view. Requires a connection to a supported remote service (e.g. GitHub)",
"scope": "window"
"markdownDescription": "Specifies whether to show pull requests (if any) associated with the worktree branch in the _Worktrees_ view. Requires a connection to a supported remote service (e.g. GitHub)",
"scope": "window",
"order": 31
},
"gitlens.views.worktrees.pullRequests.showForCommits": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to show pull requests (if any) associated with commits in the _Worktrees_ view. Requires a connection to a supported remote service (e.g. GitHub)",
"scope": "window"
"scope": "window",
"order": 32
},
"gitlens.views.worktrees.files.layout": {
"type": "string",
@ -1597,32 +1626,36 @@
"Displays files as a tree"
],
"markdownDescription": "Specifies how the _Worktrees_ view will display files",
"scope": "window"
"scope": "window",
"order": 40
},
"gitlens.views.worktrees.files.threshold": {
"type": "number",
"default": 5,
"markdownDescription": "Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the _Worktrees_ view. Only applies when `#gitlens.views.worktrees.files.layout#` is set to `auto`",
"scope": "window"
"scope": "window",
"order": 41
},
"gitlens.views.worktrees.files.compact": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to compact (flatten) unnecessary file nesting in the _Worktrees_ view. Only applies when `#gitlens.views.worktrees.files.layout#` is set to `tree` or `auto`",
"scope": "window"
"scope": "window",
"order": 42
},
"gitlens.views.worktrees.avatars": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to show avatar images instead of commit (or status) icons in the _Worktrees_ view",
"scope": "window"
"scope": "window",
"order": 50
},
"gitlens.views.worktrees.reveal": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to reveal worktrees in the _Worktrees_ view, otherwise they revealed in the _Repositories_ view",
"scope": "window",
"order": 20
"order": 60
}
}
},
@ -5821,6 +5854,26 @@
"category": "GitLens"
},
{
"command": "gitlens.views.worktrees.setShowBranchComparisonOn",
"title": "Show Branch Comparison",
"category": "GitLens"
},
{
"command": "gitlens.views.worktrees.setShowBranchComparisonOff",
"title": "Hide Branch Comparison",
"category": "GitLens"
},
{
"command": "gitlens.views.worktrees.setShowBranchPullRequestOn",
"title": "Show Branch Pull Requests",
"category": "GitLens"
},
{
"command": "gitlens.views.worktrees.setShowBranchPullRequestOff",
"title": "Hide Branch Pull Requests",
"category": "GitLens"
},
{
"command": "gitlens.enableDebugLogging",
"title": "Enable Debug Logging",
"category": "GitLens"
@ -7333,6 +7386,22 @@
"when": "false"
},
{
"command": "gitlens.views.worktrees.setShowBranchComparisonOn",
"when": "false"
},
{
"command": "gitlens.views.worktrees.setShowBranchComparisonOff",
"when": "false"
},
{
"command": "gitlens.views.worktrees.setShowBranchPullRequestOn",
"when": "false"
},
{
"command": "gitlens.views.worktrees.setShowBranchPullRequestOff",
"when": "false"
},
{
"command": "gitlens.enableDebugLogging",
"when": "config.gitlens.outputLevel != debug"
},
@ -8316,13 +8385,33 @@
"group": "5_gitlens@0"
},
{
"command": "gitlens.views.worktrees.setShowBranchComparisonOn",
"when": "view =~ /^gitlens\\.views\\.worktrees/ && !config.gitlens.views.worktrees.showBranchComparison",
"group": "5_gitlens@1"
},
{
"command": "gitlens.views.worktrees.setShowBranchComparisonOff",
"when": "view =~ /^gitlens\\.views\\.worktrees/ && config.gitlens.views.worktrees.showBranchComparison",
"group": "5_gitlens@1"
},
{
"command": "gitlens.views.worktrees.setShowBranchPullRequestOn",
"when": "view =~ /^gitlens\\.views\\.worktrees/ && !config.gitlens.views.worktrees.pullRequests.enabled && !config.gitlens.views.worktrees.pullRequests.showForBranches",
"group": "5_gitlens@2"
},
{
"command": "gitlens.views.worktrees.setShowBranchPullRequestOff",
"when": "view =~ /^gitlens\\.views\\.worktrees/ && config.gitlens.views.worktrees.pullRequests.enabled && config.gitlens.views.worktrees.pullRequests.showForBranches",
"group": "5_gitlens@2"
},
{
"command": "gitlens.views.setShowRelativeDateMarkersOn",
"when": "view =~ /^gitlens\\.views\\.(branches|commits|fileHistory|lineHistory|remotes|repositories|tags)/ && !config.gitlens.views.showRelativeDateMarkers",
"when": "view =~ /^gitlens\\.views\\.(branches|commits|fileHistory|lineHistory|remotes|repositories|tags|worktrees)/ && !config.gitlens.views.showRelativeDateMarkers",
"group": "5_gitlens@3"
},
{
"command": "gitlens.views.setShowRelativeDateMarkersOff",
"when": "view =~ /^gitlens\\.views\\.(branches|commits|fileHistory|lineHistory|remotes|repositories|tags)/ && config.gitlens.views.showRelativeDateMarkers",
"when": "view =~ /^gitlens\\.views\\.(branches|commits|fileHistory|lineHistory|remotes|repositories|tags|worktrees)/ && config.gitlens.views.showRelativeDateMarkers",
"group": "5_gitlens@3"
},
{

+ 2
- 0
src/config.ts View File

@ -661,9 +661,11 @@ export interface WorktreesViewConfig {
files: ViewsFilesConfig;
pullRequests: {
enabled: boolean;
showForBranches: boolean;
showForCommits: boolean;
};
reveal: boolean;
showBranchComparison: false | ViewShowBranchComparison.Branch;
}
export interface ViewsFilesConfig {

+ 13
- 0
src/git/models/worktree.ts View File

@ -2,6 +2,7 @@ import { Uri, workspace, WorkspaceFolder } from 'vscode';
import { Container } from '../../container';
import { memoize } from '../../system/decorators/memoize';
import { normalizePath, relative } from '../../system/path';
import { GitBranch } from './branch';
import { GitRevision } from './reference';
import type { GitStatus } from './status';
@ -47,6 +48,18 @@ export class GitWorktree {
return workspace.getWorkspaceFolder(this.uri);
}
private _branch: Promise<GitBranch | undefined> | undefined;
getBranch(): Promise<GitBranch | undefined> {
if (this.type !== 'branch' || this.branch == null) return Promise.resolve(undefined);
if (this._branch == null) {
this._branch = Container.instance.git
.getBranches(this.repoPath, { filter: b => b.name === this.branch })
.then(b => b.values[0]);
}
return this._branch;
}
private _status: Promise<GitStatus | undefined> | undefined;
getStatus(options?: { force?: boolean }): Promise<GitStatus | undefined> {
if (this.type === 'bare') return Promise.resolve(undefined);

+ 2
- 2
src/views/nodes/branchNode.ts View File

@ -131,8 +131,6 @@ export class BranchNode
async getChildren(): Promise<ViewNode[]> {
if (this._children == null) {
const children = [];
let prPromise;
if (
this.view.config.pullRequests.enabled &&
@ -168,6 +166,8 @@ export class BranchNode
);
if (log == null) return [new MessageNode(this.view, this, 'No commits could be found.')];
const children = [];
let prInsertIndex = 0;
if (this.options.showComparison !== false && !(this.view instanceof RemotesView)) {

+ 3
- 2
src/views/nodes/compareBranchNode.ts View File

@ -12,12 +12,13 @@ import { pluralize } from '../../system/string';
import { BranchesView } from '../branchesView';
import { CommitsView } from '../commitsView';
import { RepositoriesView } from '../repositoriesView';
import { WorktreesView } from '../worktreesView';
import { RepositoryNode } from './repositoryNode';
import { CommitsQueryResults, ResultsCommitsNode } from './resultsCommitsNode';
import { FilesQueryResults, ResultsFilesNode } from './resultsFilesNode';
import { ContextValues, ViewNode } from './viewNode';
export class CompareBranchNode extends ViewNode<BranchesView | CommitsView | RepositoriesView> {
export class CompareBranchNode extends ViewNode<BranchesView | CommitsView | RepositoriesView | WorktreesView> {
static key = ':compare-branch';
static getId(repoPath: string, name: string, root: boolean): string {
return `${RepositoryNode.getId(repoPath)}${this.key}(${name})${root ? ':root' : ''}`;
@ -28,7 +29,7 @@ export class CompareBranchNode extends ViewNode
constructor(
uri: GitUri,
view: BranchesView | CommitsView | RepositoriesView,
view: BranchesView | CommitsView | RepositoriesView | WorktreesView,
parent: ViewNode,
public readonly branch: GitBranch,
private showComparison: ViewShowBranchComparison,

+ 114
- 28
src/views/nodes/worktreeNode.ts View File

@ -1,7 +1,15 @@
import { MarkdownString, ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri, window } from 'vscode';
import { GlyphChars } from '../../constants';
import { GitUri } from '../../git/gitUri';
import { GitLog, GitRemote, GitRemoteType, GitRevision, GitWorktree } from '../../git/models';
import {
GitBranch,
GitLog,
GitRemote,
GitRemoteType,
GitRevision,
GitWorktree,
PullRequestState,
} from '../../git/models';
import { gate } from '../../system/decorators/gate';
import { debug } from '../../system/decorators/log';
import { map } from '../../system/iterable';
@ -10,7 +18,9 @@ import { RepositoriesView } from '../repositoriesView';
import { WorktreesView } from '../worktreesView';
import { CommitNode } from './commitNode';
import { LoadMoreNode, MessageNode } from './common';
import { CompareBranchNode } from './compareBranchNode';
import { insertDateMarkers } from './helpers';
import { PullRequestNode } from './pullRequestNode';
import { RepositoryNode } from './repositoryNode';
import { UncommittedFilesNode } from './UncommittedFilesNode';
import { ContextValues, ViewNode } from './viewNode';
@ -21,6 +31,9 @@ export class WorktreeNode extends ViewNode {
return `${RepositoryNode.getId(repoPath)}${this.key}(${uri.path})`;
}
private _branch: GitBranch | undefined;
private _children: ViewNode[] | undefined;
constructor(
uri: GitUri,
view: WorktreesView | RepositoriesView,
@ -43,29 +56,106 @@ export class WorktreeNode extends ViewNode {
}
async getChildren(): Promise<ViewNode[]> {
const log = await this.getLog();
if (log == null) return [new MessageNode(this.view, this, 'No commits could be found.')];
const getBranchAndTagTips = await this.view.container.git.getBranchesAndTagsTipsFn(this.uri.repoPath);
const children = [
...insertDateMarkers(
map(
log.commits.values(),
c => new CommitNode(this.view, this, c, undefined, undefined, getBranchAndTagTips),
if (this._children == null) {
const branch = this._branch;
let prPromise;
if (
branch != null &&
this.view.config.pullRequests.enabled &&
this.view.config.pullRequests.showForBranches &&
(branch.upstream != null || branch.remote)
) {
prPromise = branch.getAssociatedPullRequest({
include: [PullRequestState.Open, PullRequestState.Merged],
});
}
const range =
branch != null && !branch.remote
? await this.view.container.git.getBranchAheadRange(branch)
: undefined;
const [log, getBranchAndTagTips, status, unpublishedCommits] = await Promise.all([
this.getLog(),
this.view.container.git.getBranchesAndTagsTipsFn(this.uri.repoPath),
this.worktree.getStatus(),
range
? this.view.container.git.getLogRefsOnly(this.uri.repoPath!, {
limit: 0,
ref: range,
})
: undefined,
]);
if (log == null) return [new MessageNode(this.view, this, 'No commits could be found.')];
const children = [];
let prInsertIndex = 0;
if (branch != null && this.view.config.showBranchComparison !== false) {
prInsertIndex++;
children.push(
new CompareBranchNode(
this.uri,
this.view,
this,
branch,
this.view.config.showBranchComparison,
this.splatted,
),
);
}
children.push(
...insertDateMarkers(
map(
log.commits.values(),
c =>
new CommitNode(
this.view,
this,
c,
unpublishedCommits?.has(c.ref),
branch,
getBranchAndTagTips,
),
),
this,
),
this,
),
];
);
if (log.hasMore) {
children.push(new LoadMoreNode(this.view, this, children[children.length - 1]));
}
if (log.hasMore) {
children.push(new LoadMoreNode(this.view, this, children[children.length - 1]));
}
if (status?.hasChanges) {
children.splice(0, 0, new UncommittedFilesNode(this.view, this, status, undefined));
}
if (prPromise != null) {
const pr = await prPromise;
if (pr != null) {
children.splice(prInsertIndex, 0, new PullRequestNode(this.view, this, pr, branch!));
}
// const pr = await Promise.race([
// prPromise,
// new Promise<null>(resolve => setTimeout(() => resolve(null), 100)),
// ]);
// if (pr != null) {
// children.splice(prInsertIndex, 0, new PullRequestNode(this.view, this, pr, this.branch));
// } else if (pr === null) {
// void prPromise.then(pr => {
// if (pr == null) return;
// void this.triggerChange();
// });
// }
}
const status = await this.worktree.getStatus();
if (status?.hasChanges) {
children.splice(0, 0, new UncommittedFilesNode(this.view, this, status, undefined));
this._children = children;
}
return children;
return this._children;
}
async getTreeItem(): Promise<TreeItem> {
@ -97,14 +187,8 @@ export class WorktreeNode extends ViewNode {
);
break;
case 'branch': {
const [branch, status] = await Promise.all([
this.worktree.branch
? this.view.container.git
.getBranches(this.uri.repoPath, { filter: b => b.name === this.worktree.branch })
.then(b => b.values[0])
: undefined,
this.worktree.getStatus(),
]);
const [branch, status] = await Promise.all([this.worktree.getBranch(), this.worktree.getStatus()]);
this._branch = branch;
tooltip.appendMarkdown(
`${this.worktree.main ? '$(pass) ' : ''}Worktree for Branch $(git-branch) ${
@ -231,6 +315,7 @@ export class WorktreeNode extends ViewNode {
@gate()
@debug()
override refresh(reset?: boolean) {
this._children = undefined;
if (reset) {
this._log = undefined;
}
@ -269,6 +354,7 @@ export class WorktreeNode extends ViewNode {
this._log = log;
this.limit = log?.count;
this._children = undefined;
void this.triggerChange(false);
}
}

+ 33
- 1
src/views/worktreesView.ts View File

@ -9,7 +9,7 @@ import {
TreeItemCollapsibleState,
window,
} from 'vscode';
import { configuration, ViewFilesLayout, WorktreesViewConfig } from '../configuration';
import { configuration, ViewFilesLayout, ViewShowBranchComparison, WorktreesViewConfig } from '../configuration';
import { Container } from '../container';
import { PremiumFeatures } from '../git/gitProvider';
import { GitUri } from '../git/gitUri';
@ -171,6 +171,26 @@ export class WorktreesView extends ViewBase
() => this.setShowAvatars(false),
this,
),
commands.registerCommand(
this.getQualifiedCommand('setShowBranchComparisonOn'),
() => this.setShowBranchComparison(true),
this,
),
commands.registerCommand(
this.getQualifiedCommand('setShowBranchComparisonOff'),
() => this.setShowBranchComparison(false),
this,
),
commands.registerCommand(
this.getQualifiedCommand('setShowBranchPullRequestOn'),
() => this.setShowBranchPullRequest(true),
this,
),
commands.registerCommand(
this.getQualifiedCommand('setShowBranchPullRequestOff'),
() => this.setShowBranchPullRequest(false),
this,
),
];
}
@ -260,4 +280,16 @@ export class WorktreesView extends ViewBase
private setShowAvatars(enabled: boolean) {
return configuration.updateEffective(`views.${this.configKey}.avatars` as const, enabled);
}
private setShowBranchComparison(enabled: boolean) {
return configuration.updateEffective(
`views.${this.configKey}.showBranchComparison` as const,
enabled ? ViewShowBranchComparison.Branch : false,
);
}
private async setShowBranchPullRequest(enabled: boolean) {
await configuration.updateEffective(`views.${this.configKey}.pullRequests.showForBranches` as const, enabled);
await configuration.updateEffective(`views.${this.configKey}.pullRequests.enabled` as const, enabled);
}
}

+ 190
- 0
src/webviews/apps/settings/partials/views.worktrees.html View File

@ -0,0 +1,190 @@
<section id="worktrees-view" class="section--settings section--collapsible">
<div class="section__header">
<h2>
Worktrees view
<a
class="link__learn-more"
title="Learn more"
href="https://github.com/eamodio/vscode-gitlens/#worktrees-view-"
>
<i class="icon icon__info"></i>
</a>
</h2>
<p class="section__header-hint">
Adds a
<a class="command command--show-view" title="Show View in Side Bar" href="command:gitlens.showWorktreesView"
>Worktrees view</a
>
to visualize, explore, and manage Git worktrees
</p>
</div>
<div class="section__collapsible">
<div class="section__group">
<div class="section__content">
<div class="settings settings--fixed ml-1">
<div class="setting">
<div class="setting__input">
<input
id="worktrees.promptForLocation"
name="worktrees.promptForLocation"
type="checkbox"
data-setting
/>
<label for="worktrees.promptForLocation">Always ask where to put new worktrees</label>
</div>
</div>
<div class="setting">
<div class="setting__input">
<label for="worktrees.defaultLocation">Default&nbsp;worktree&nbsp;location</label>
<input
id="worktrees.defaultLocation"
name="worktrees.defaultLocation"
type="text"
placeholder="absolute path to put new worktrees into"
data-setting
/>
</div>
<p class="setting__hint">
<i class="icon icon__info"></i> Can be configured on a per-workspace or per-folder basis
</p>
</div>
<div class="section__group">
<div class="section__content">
<div class="settings settings--fixed">
<div class="setting">
<div class="setting__input">
<input
id="views.worktrees.pullRequests.enabled"
name="views.worktrees.pullRequests.enabled"
type="checkbox"
data-setting
/>
<label for="views.worktrees.pullRequests.enabled"
>Show associated pull requests</label
>
</div>
<p class="setting__hint">
Requires a connection to a supported remote service (e.g. GitHub)
</p>
</div>
<div class="settings settings--fixed ml-2">
<div class="setting" data-enablement="views.worktrees.pullRequests.enabled">
<div class="setting__input">
<input
id="views.worktrees.pullRequests.showForBranches"
name="views.worktrees.pullRequests.showForBranches"
type="checkbox"
data-setting
disabled
/>
<label for="views.worktrees.pullRequests.showForBranches"
>Show the pull request associated with the worktree branch</label
>
</div>
</div>
<div class="setting" data-enablement="views.worktrees.pullRequests.enabled">
<div class="setting__input">
<input
id="views.worktrees.pullRequests.showForCommits"
name="views.worktrees.pullRequests.showForCommits"
type="checkbox"
data-setting
disabled
/>
<label for="views.worktrees.pullRequests.showForCommits"
>Show the pull request that introduced each commit</label
>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="setting">
<div class="setting__input">
<label for="views.worktrees.files.layout">Layout files</label>
<div class="select-container">
<select
id="views.worktrees.files.layout"
name="views.worktrees.files.layout"
data-setting
>
<option value="auto">automatically</option>
<option value="list">as a list</option>
<option value="tree">as a tree</option>
</select>
</div>
</div>
<p class="setting__hint" data-visibility="views.worktrees.files.layout =auto">
Chooses the best layout based on the number of files at each nesting level
</p>
</div>
<div class="setting">
<div class="setting__input">
<input
id="views.worktrees.files.compact"
name="views.worktrees.files.compact"
type="checkbox"
data-setting
/>
<label for="views.worktrees.files.compact">Use compact file layout</label>
</div>
<p class="setting__hint">Compacts (flattens) unnecessary nesting when using a tree layouts</p>
</div>
<div class="setting">
<div class="setting__input">
<input
id="views.worktrees.avatars"
name="views.worktrees.avatars"
type="checkbox"
data-setting
/>
<label for="views.worktrees.avatars">Use author avatars</label>
</div>
</div>
</div>
</div>
<div class="section__preview">
<img
class="image__preview hidden"
src="#{root}/images/settings/worktrees-view-pr.webp"
data-visibility="views.worktrees.pullRequests.enabled &amp; views.worktrees.pullRequests.showForBranches"
/>
<img
class="image__preview hidden"
src="#{root}/images/settings/worktrees-view.webp"
data-visibility="views.worktrees.pullRequests.enabled =false"
/>
<img
class="image__preview hidden"
src="#{root}/images/settings/worktrees-view.webp"
data-visibility="views.worktrees.pullRequests.enabled &amp; views.worktrees.pullRequests.showForBranches =false"
/>
</div>
</div>
<div class="section__group">
<p class="section__hint">
<i class="icon icon__info"></i> For more options, open
<a
class="command"
title="Open Settings"
href="command:workbench.action.openSettings?%22gitlens.views.worktrees%22"
>Settings</a
>
and search for <b><i>gitlens.views.worktrees</i></b> or
<b><i>gitlens.views</i></b>
</p>
</div>
</div>
</section>

+ 11
- 0
src/webviews/apps/settings/settings.html View File

@ -241,6 +241,8 @@
<!-- prettier-ignore -->
<%= require('html-loader?{"esModule":false}!./partials/views.tags.html') %>
<!-- prettier-ignore -->
<%= require('html-loader?{"esModule":false}!./partials/views.worktrees.html') %>
<!-- prettier-ignore -->
<%= require('html-loader?{"esModule":false}!./partials/views.contributors.html') %>
<!-- prettier-ignore -->
<%= require('html-loader?{"esModule":false}!./partials/views.searchAndCompare.html') %>
@ -388,6 +390,15 @@
<a
class="sidebar__jump-link"
data-action="jump"
href="#worktrees-view"
title="Jump to Worktrees view settings"
>Worktrees view</a
>
</li>
<li>
<a
class="sidebar__jump-link"
data-action="jump"
href="#contributors-view"
title="Jump to Contributors view settings"
>Contributors view</a

Loading…
Cancel
Save