From 1adc4be6877574c2bd027e7ed85ea1a10f99e9f5 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Wed, 16 Feb 2022 18:05:55 -0500 Subject: [PATCH] Adds branch comparisons to worktrees Adds associated PRs to worktree branches Adds worktrees to the settings page Adds unpublished markers to worktrees --- README.md | 32 +++- package.json | 127 +++++++++++--- src/config.ts | 2 + src/git/models/worktree.ts | 13 ++ src/views/nodes/branchNode.ts | 4 +- src/views/nodes/compareBranchNode.ts | 5 +- src/views/nodes/worktreeNode.ts | 142 ++++++++++++--- src/views/worktreesView.ts | 34 +++- .../apps/settings/partials/views.worktrees.html | 190 +++++++++++++++++++++ src/webviews/apps/settings/settings.html | 11 ++ 10 files changed, 500 insertions(+), 60 deletions(-) create mode 100644 src/webviews/apps/settings/partials/views.worktrees.html diff --git a/README.md b/README.md index 2068348..4e6598f 100644 --- a/README.md +++ b/README.md @@ -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

`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
`list` - displays files as a list
`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
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

`false` - hides the branch comparison
`branch` - compares the current branch with a user-selected reference
`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.
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

`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
`list` - displays files as a list
`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
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

`false` - hides the branch comparison
`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.
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

`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
`list` - displays files as a list
`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
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

`false` - hides the branch comparison
`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
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.
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

`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
`list` - displays files as a list
`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
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

`false` - hides the branch comparison
`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') diff --git a/package.json b/package.json index 5b21ad3..8ddd4a0 100644 --- a/package.json +++ b/package.json @@ -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" }, { diff --git a/src/config.ts b/src/config.ts index 26a8fc2..904d3d0 100644 --- a/src/config.ts +++ b/src/config.ts @@ -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 { diff --git a/src/git/models/worktree.ts b/src/git/models/worktree.ts index 630da94..c3cd7c4 100644 --- a/src/git/models/worktree.ts +++ b/src/git/models/worktree.ts @@ -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 | undefined; + getBranch(): Promise { + 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 | undefined; getStatus(options?: { force?: boolean }): Promise { if (this.type === 'bare') return Promise.resolve(undefined); diff --git a/src/views/nodes/branchNode.ts b/src/views/nodes/branchNode.ts index bcf9397..58b22c8 100644 --- a/src/views/nodes/branchNode.ts +++ b/src/views/nodes/branchNode.ts @@ -131,8 +131,6 @@ export class BranchNode async getChildren(): Promise { 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)) { diff --git a/src/views/nodes/compareBranchNode.ts b/src/views/nodes/compareBranchNode.ts index f4046a8..aa7414d 100644 --- a/src/views/nodes/compareBranchNode.ts +++ b/src/views/nodes/compareBranchNode.ts @@ -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 { +export class CompareBranchNode extends ViewNode { 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 { 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 { - 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(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 { @@ -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); } } diff --git a/src/views/worktreesView.ts b/src/views/worktreesView.ts index bf74c6e..1c80101 100644 --- a/src/views/worktreesView.ts +++ b/src/views/worktreesView.ts @@ -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 +
+

+ Worktrees view + + + +

+ +

+ Adds a + Worktrees view + to visualize, explore, and manage Git worktrees +

+
+ +
+
+
+
+
+
+ + +
+
+ +
+
+ + +
+

+ Can be configured on a per-workspace or per-folder basis +

+
+ +
+
+
+
+
+ + +
+

+ Requires a connection to a supported remote service (e.g. GitHub) +

+
+ +
+
+
+ + +
+
+ +
+
+ + +
+
+
+
+
+
+ +
+
+ +
+ +
+
+

+ Chooses the best layout based on the number of files at each nesting level +

+
+ +
+
+ + +
+

Compacts (flattens) unnecessary nesting when using a tree layouts

+
+ +
+
+ + +
+
+
+
+ +
+ + + +
+
+ +
+

+ For more options, open + Settings + and search for gitlens.views.worktrees or + gitlens.views +

+
+
+ diff --git a/src/webviews/apps/settings/settings.html b/src/webviews/apps/settings/settings.html index e54d497..0e97b86 100644 --- a/src/webviews/apps/settings/settings.html +++ b/src/webviews/apps/settings/settings.html @@ -241,6 +241,8 @@ <%= require('html-loader?{"esModule":false}!./partials/views.tags.html') %> + <%= require('html-loader?{"esModule":false}!./partials/views.worktrees.html') %> + <%= require('html-loader?{"esModule":false}!./partials/views.contributors.html') %> <%= require('html-loader?{"esModule":false}!./partials/views.searchAndCompare.html') %> @@ -388,6 +390,15 @@ Worktrees view + +
  • + Contributors view