Skip to content

Commit 2b37aec

Browse files
Error handling of create worktree and fix create worktree... command from command palette (microsoft#257172)
* esc when creating worktree name cancels create operation * Find main repo for createworktree command palette to prevent repo picker * error handling of creating worktree * add back repo picker for create worktree... command
1 parent c7ad864 commit 2b37aec

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

extensions/git/src/api/git.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,5 +441,6 @@ export const enum GitErrorCodes {
441441
TagConflict = 'TagConflict',
442442
CherryPickEmpty = 'CherryPickEmpty',
443443
CherryPickConflict = 'CherryPickConflict',
444-
WorktreeContainsChanges = 'WorktreeContainsChanges'
444+
WorktreeContainsChanges = 'WorktreeContainsChanges',
445+
WorktreeAlreadyExists = 'WorktreeAlreadyExists'
445446
}

extensions/git/src/commands.ts

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3430,6 +3430,10 @@ export class CommandCenter {
34303430
dispose(disposables);
34313431
inputBox.dispose();
34323432

3433+
if (!worktreeName) {
3434+
return;
3435+
}
3436+
34333437
// Default to view parent directory of repository root
34343438
const defaultUri = Uri.file(path.dirname(repository.root));
34353439

@@ -3451,10 +3455,40 @@ export class CommandCenter {
34513455

34523456
worktreePath = path.join(uris[0].fsPath, worktreeName);
34533457

3454-
await repository.worktree({
3455-
name: name,
3456-
path: worktreePath,
3457-
});
3458+
try {
3459+
await repository.worktree({ name: name, path: worktreePath });
3460+
} catch (err) {
3461+
if (err.gitErrorCode === GitErrorCodes.WorktreeAlreadyExists) {
3462+
const errorMessage = err.stderr;
3463+
const match = errorMessage.match(/worktree at '([^']+)'/) || errorMessage.match(/'([^']+)'/);
3464+
const path = match ? match[1] : undefined;
3465+
3466+
if (!path) {
3467+
return;
3468+
}
3469+
3470+
const openWorktree = l10n.t('Open in current window');
3471+
const openWorktreeInNewWindow = l10n.t('Open in new window');
3472+
const message = l10n.t(errorMessage || 'A worktree for branch \'{0}\' already exists at \'{1}\'.', name, path);
3473+
const choice = await window.showWarningMessage(message, { modal: true }, openWorktree, openWorktreeInNewWindow);
3474+
3475+
const worktreeRepository = this.model.getRepository(path) || this.model.getRepository(Uri.file(path));
3476+
3477+
if (!worktreeRepository) {
3478+
return;
3479+
}
3480+
3481+
if (choice === openWorktree) {
3482+
await this.openWorktreeInCurrentWindow(worktreeRepository);
3483+
} else if (choice === openWorktreeInNewWindow) {
3484+
await this.openWorktreeInNewWindow(worktreeRepository);
3485+
}
3486+
3487+
return;
3488+
}
3489+
3490+
throw err;
3491+
}
34583492
}
34593493

34603494
@command('git.deleteWorktree', { repository: true })

extensions/git/src/git.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,8 @@ function getGitErrorCode(stderr: string): string | undefined {
351351
return GitErrorCodes.NotASafeGitRepository;
352352
} else if (/contains modified or untracked files|use --force to delete it/.test(stderr)) {
353353
return GitErrorCodes.WorktreeContainsChanges;
354+
} else if (/is already used by worktree at|already exists/.test(stderr)) {
355+
return GitErrorCodes.WorktreeAlreadyExists;
354356
}
355357

356358
return undefined;

0 commit comments

Comments
 (0)