From b78acaed0e7d8fa74166c170f8c87089122a3c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christy=20=F0=9F=98=BA?= Date: Tue, 22 Jul 2025 15:10:03 -0700 Subject: [PATCH] worktree error handling in creation of worktrees and checking out branches (#257328) * worktree error handling in creation of worktrees and checking out branches * code clean up --- extensions/git/src/commands.ts | 71 ++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index ec2223c7f17..224494fd164 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -2917,10 +2917,15 @@ export class CommandCenter { try { await item.run(repository, opts); } catch (err) { - if (err.gitErrorCode !== GitErrorCodes.DirtyWorkTree) { + if (err.gitErrorCode !== GitErrorCodes.DirtyWorkTree && err.gitErrorCode !== GitErrorCodes.WorktreeAlreadyExists) { throw err; } + if (err.gitErrorCode === GitErrorCodes.WorktreeAlreadyExists) { + this.handleWorktreeError(err); + return false; + } + const stash = l10n.t('Stash & Checkout'); const migrate = l10n.t('Migrate Changes'); const force = l10n.t('Force Checkout'); @@ -3458,39 +3463,47 @@ export class CommandCenter { try { await repository.worktree({ name: name, path: worktreePath }); } catch (err) { - if (err.gitErrorCode === GitErrorCodes.WorktreeAlreadyExists) { - const errorMessage = err.stderr; - const match = errorMessage.match(/worktree at '([^']+)'/) || errorMessage.match(/'([^']+)'/); - const path = match ? match[1] : undefined; - - if (!path) { - return; - } - - const openWorktree = l10n.t('Open in current window'); - const openWorktreeInNewWindow = l10n.t('Open in new window'); - const message = l10n.t(errorMessage || 'A worktree for branch \'{0}\' already exists at \'{1}\'.', name, path); - const choice = await window.showWarningMessage(message, { modal: true }, openWorktree, openWorktreeInNewWindow); - - const worktreeRepository = this.model.getRepository(path) || this.model.getRepository(Uri.file(path)); - - if (!worktreeRepository) { - return; - } - - if (choice === openWorktree) { - await this.openWorktreeInCurrentWindow(worktreeRepository); - } else if (choice === openWorktreeInNewWindow) { - await this.openWorktreeInNewWindow(worktreeRepository); - } - - return; + if (err.gitErrorCode !== GitErrorCodes.WorktreeAlreadyExists) { + throw err; } - throw err; + this.handleWorktreeError(err); + return; + } } + private async handleWorktreeError(err: any): Promise { + const errorMessage = err.stderr; + const match = errorMessage.match(/worktree at '([^']+)'/) || errorMessage.match(/'([^']+)'/); + const path = match ? match[1] : undefined; + + if (!path) { + return; + } + + const worktreeRepository = this.model.getRepository(path) || this.model.getRepository(Uri.file(path)); + + if (!worktreeRepository) { + return; + } + + const openWorktree = l10n.t('Open in current window'); + const openWorktreeInNewWindow = l10n.t('Open in new window'); + const message = l10n.t(errorMessage); + const choice = await window.showWarningMessage(message, { modal: true }, openWorktree, openWorktreeInNewWindow); + + + + if (choice === openWorktree) { + await this.openWorktreeInCurrentWindow(worktreeRepository); + } else if (choice === openWorktreeInNewWindow) { + await this.openWorktreeInNewWindow(worktreeRepository); + } + + return; + } + @command('git.deleteWorktree', { repository: true }) async deleteWorktree(repository: Repository): Promise { if (!repository.dotGit.commonPath) {