Procházet zdrojové kódy

Fixes issues with missing worktrees

main
Eric Amodio před 1 rokem
rodič
revize
acc97f7084
8 změnil soubory, kde provedl 95 přidání a 27 odebrání
  1. +1
    -0
      CHANGELOG.md
  2. +10
    -1
      package.json
  3. +5
    -1
      src/commands/git/worktree.ts
  4. +16
    -5
      src/commands/quickCommand.steps.ts
  5. +2
    -1
      src/constants.ts
  6. +6
    -1
      src/quickpicks/items/gitCommands.ts
  7. +30
    -3
      src/views/nodes/worktreeNode.ts
  8. +25
    -15
      src/views/worktreesView.ts

+ 1
- 0
CHANGELOG.md Zobrazit soubor

@ -24,6 +24,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
### Fixed
- Fixes [#2823](https://github.com/gitkraken/vscode-gitlens/issues/2823) - Handle stdout/stderr Buffers in shell run() — thanks to [PR #2824](https://github.com/gitkraken/vscode-gitlens/pull/2824) by Victor Hallberg ([@mogelbrod](https://github.com/mogelbrod))
- Fixes issues with missing worktrees breaking the Worktrees view and quick pick menus
## [14.1.1] - 2023-07-18

+ 10
- 1
package.json Zobrazit soubor

@ -4268,7 +4268,7 @@
}
},
{
"id": "gitlens.decorations.worktreeView.hasUncommittedChangesForegroundColor",
"id": "gitlens.decorations.worktreeHasUncommittedChangesForegroundColor",
"description": "Specifies the decoration foreground color for worktrees that have uncommitted changes",
"defaults": {
"light": "#895503",
@ -4277,6 +4277,15 @@
}
},
{
"id": "gitlens.decorations.worktreeMissingForegroundColor",
"description": "Specifies the decoration foreground color for worktrees cannot be found on disk",
"defaults": {
"light": "#ad0707",
"dark": "#c74e39",
"highContrast": "#c74e39"
}
},
{
"id": "gitlens.graphLane1Color",
"description": "Specifies the color for the first commit lane of the _Commit Graph_ visualization",
"defaults": {

+ 5
- 1
src/commands/git/worktree.ts Zobrazit soubor

@ -723,7 +723,11 @@ export class WorktreeGitCommand extends QuickCommand {
try {
if (force) {
const worktree = context.worktrees.find(wt => wt.uri.toString() === uri.toString());
const status = await worktree?.getStatus();
let status;
try {
status = await worktree?.getStatus();
} catch {}
if (status?.hasChanges ?? false) {
const confirm: MessageItem = { title: 'Force Delete' };
const cancel: MessageItem = { title: 'Cancel', isCloseAffordance: true };

+ 16
- 5
src/commands/quickCommand.steps.ts Zobrazit soubor

@ -229,18 +229,29 @@ export async function getWorktrees(
return Promise.all<WorktreeQuickPickItem>([
...worktrees
.filter(w => filter == null || filter(w))
.map(async w =>
createWorktreeQuickPickItem(
.map(async w => {
let missing = false;
let status;
if (includeStatus) {
try {
status = await w.getStatus();
} catch {
missing = true;
}
}
return createWorktreeQuickPickItem(
w,
picked != null &&
(typeof picked === 'string' ? w.uri.toString() === picked : picked.includes(w.uri.toString())),
missing,
{
buttons: buttons,
path: true,
status: includeStatus ? await w.getStatus() : undefined,
status: status,
},
),
),
);
}),
]);
}

+ 2
- 1
src/constants.ts Zobrazit soubor

@ -77,7 +77,8 @@ export type Colors =
| `${typeof extensionPrefix}.decorations.workspaceCurrentForegroundColor`
| `${typeof extensionPrefix}.decorations.workspaceRepoMissingForegroundColor`
| `${typeof extensionPrefix}.decorations.workspaceRepoOpenForegroundColor`
| `${typeof extensionPrefix}.decorations.worktreeView.hasUncommittedChangesForegroundColor`
| `${typeof extensionPrefix}.decorations.worktreeHasUncommittedChangesForegroundColor`
| `${typeof extensionPrefix}.decorations.worktreeMissingForegroundColor`
| `${typeof extensionPrefix}.gutterBackgroundColor`
| `${typeof extensionPrefix}.gutterForegroundColor`
| `${typeof extensionPrefix}.gutterUncommittedForegroundColor`

+ 6
- 1
src/quickpicks/items/gitCommands.ts Zobrazit soubor

@ -469,6 +469,7 @@ export interface WorktreeQuickPickItem extends QuickPickItemOfT {
export function createWorktreeQuickPickItem(
worktree: GitWorktree,
picked?: boolean,
missing?: boolean,
options?: {
alwaysShow?: boolean;
buttons?: QuickInputButton[];
@ -510,7 +511,11 @@ export function createWorktreeQuickPickItem(
const item: WorktreeQuickPickItem = {
label: `${icon}${GlyphChars.Space}${label}${options?.checked ? pad('$(check)', 2) : ''}`,
description: description,
detail: options?.path ? `In $(folder) ${worktree.friendlyPath}` : undefined,
detail: options?.path
? missing
? `${GlyphChars.Warning} Unable to locate $(folder) ${worktree.friendlyPath}`
: `In $(folder) ${worktree.friendlyPath}`
: undefined,
alwaysShow: options?.alwaysShow,
buttons: options?.buttons,
picked: picked,

+ 30
- 3
src/views/nodes/worktreeNode.ts Zobrazit soubor

@ -12,6 +12,7 @@ import { getContext } from '../../system/context';
import { gate } from '../../system/decorators/gate';
import { debug } from '../../system/decorators/log';
import { map } from '../../system/iterable';
import { Logger } from '../../system/logger';
import type { Deferred } from '../../system/promise';
import { defer, getSettledValue } from '../../system/promise';
import { pad } from '../../system/string';
@ -207,6 +208,8 @@ export class WorktreeNode extends ViewNode {
} `
: '';
let missing = false;
switch (this.worktree.type) {
case 'bare':
icon = new ThemeIcon('folder');
@ -217,7 +220,13 @@ export class WorktreeNode extends ViewNode {
);
break;
case 'branch': {
const [branch, status] = await Promise.all([this.worktree.getBranch(), this.worktree.getStatus()]);
const [branchResult, statusResult] = await Promise.allSettled([
this.worktree.getBranch(),
this.worktree.getStatus(),
]);
const branch = getSettledValue(branchResult);
const status = getSettledValue(statusResult);
this._branch = branch;
tooltip.appendMarkdown(
@ -236,6 +245,9 @@ export class WorktreeNode extends ViewNode {
expand: true,
})}`,
);
} else if (statusResult.status === 'rejected') {
Logger.error(statusResult.reason, 'Worktree status failed');
missing = true;
}
if (branch != null) {
@ -314,7 +326,14 @@ export class WorktreeNode extends ViewNode {
)}${indicators}\\\n\`${this.worktree.friendlyPath}\``,
);
const status = await this.worktree.getStatus();
let status;
try {
status = await this.worktree.getStatus();
} catch (ex) {
Logger.error(ex, 'Worktree status failed');
missing = true;
}
if (status != null) {
hasChanges = status.hasChanges;
tooltip.appendMarkdown(
@ -335,6 +354,10 @@ export class WorktreeNode extends ViewNode {
tooltip.appendMarkdown(`\n\n$(loading~spin) Loading associated pull request${GlyphChars.Ellipsis}`);
}
if (missing) {
tooltip.appendMarkdown(`\n\n${GlyphChars.Warning} Unable to locate worktree path`);
}
const item = new TreeItem(this.worktree.name, TreeItemCollapsibleState.Collapsed);
item.id = this.id;
item.description = description;
@ -348,7 +371,11 @@ export class WorktreeNode extends ViewNode {
? new ThemeIcon('check')
: icon;
item.tooltip = tooltip;
item.resourceUri = hasChanges ? Uri.parse('gitlens-view://worktree/changes') : undefined;
item.resourceUri = missing
? Uri.parse('gitlens-view://worktree/missing')
: hasChanges
? Uri.parse('gitlens-view://worktree/changes')
: undefined;
return item;
}

+ 25
- 15
src/views/worktreesView.ts Zobrazit soubor

@ -3,7 +3,7 @@ import { ProgressLocation, ThemeColor, TreeItem, TreeItemCollapsibleState, windo
import type { WorktreesViewConfig } from '../config';
import { ViewFilesLayout, ViewShowBranchComparison } from '../config';
import type { Colors } from '../constants';
import { Commands } from '../constants';
import { Commands, GlyphChars } from '../constants';
import type { Container } from '../container';
import { PlusFeatures } from '../features';
import { GitUri } from '../git/gitUri';
@ -100,21 +100,31 @@ export class WorktreesView extends ViewBase<'worktrees', WorktreesViewNode, Work
this.disposables.push(
window.registerFileDecorationProvider({
provideFileDecoration: (uri, _token) => {
if (
uri.scheme !== 'gitlens-view' ||
uri.authority !== 'worktree' ||
!uri.path.includes('/changes')
) {
return undefined;
if (uri.scheme !== 'gitlens-view' || uri.authority !== 'worktree') return undefined;
const [, status] = uri.path.split('/');
switch (status) {
case 'changes':
return {
badge: '●',
color: new ThemeColor(
'gitlens.decorations.worktreeHasUncommittedChangesForegroundColor' as Colors,
),
tooltip: 'Has Uncommitted Changes',
};
case 'missing':
return {
badge: GlyphChars.Warning,
color: new ThemeColor(
'gitlens.decorations.worktreeMissingForegroundColor' satisfies Colors,
),
tooltip: '',
};
default:
return undefined;
}
return {
badge: '●',
color: new ThemeColor(
'gitlens.decorations.worktreeView.hasUncommittedChangesForegroundColor' as Colors,
),
tooltip: 'Has Uncommitted Changes',
};
},
}),
);

Načítá se…
Zrušit
Uložit