Git - cleanup delete worktree command implementation (#278018)

This commit is contained in:
Ladislau Szomoru
2025-11-18 08:17:55 +00:00
committed by GitHub
parent 5bad6a3248
commit ae77536e70
5 changed files with 55 additions and 72 deletions

View File

@@ -246,19 +246,7 @@ class WorktreeDeleteItem extends WorktreeItem {
return;
}
try {
await mainRepository.deleteWorktree(this.worktree.path);
} catch (err) {
if (err.gitErrorCode === GitErrorCodes.WorktreeContainsChanges) {
const forceDelete = l10n.t('Force Delete');
const message = l10n.t('The worktree contains modified or untracked files. Do you want to force delete?');
const choice = await window.showWarningMessage(message, { modal: true }, forceDelete);
if (choice === forceDelete) {
await mainRepository.deleteWorktree(this.worktree.path, { force: true });
}
}
}
await mainRepository.deleteWorktree(this.worktree.path);
}
}
@@ -3841,43 +3829,7 @@ export class CommandCenter {
return;
}
@command('git.deleteWorktree', { repository: true, repositoryFilter: ['worktree'] })
async deleteWorktree(repository: Repository): Promise<void> {
if (!repository.dotGit.commonPath) {
return;
}
const mainRepository = this.model.getRepository(path.dirname(repository.dotGit.commonPath));
if (!mainRepository) {
await window.showErrorMessage(l10n.t('You cannot delete the worktree you are currently in. Please switch to the main repository first.'), { modal: true });
return;
}
try {
await mainRepository.deleteWorktree(repository.root);
// Dispose worktree repository
this.model.disposeRepository(repository);
} catch (err) {
if (err.gitErrorCode === GitErrorCodes.WorktreeContainsChanges) {
const forceDelete = l10n.t('Force Delete');
const message = l10n.t('The worktree contains modified or untracked files. Do you want to force delete?');
const choice = await window.showWarningMessage(message, { modal: true }, forceDelete);
if (choice === forceDelete) {
await mainRepository.deleteWorktree(repository.root, { force: true });
// Dispose worktree repository
this.model.disposeRepository(repository);
}
return;
}
throw err;
}
}
@command('git.deleteWorktreeFromPalette', { repository: true, repositoryFilter: ['repository', 'submodule'] })
@command('git.deleteWorktree', { repository: true, repositoryFilter: ['repository', 'submodule'] })
async deleteWorktreeFromPalette(repository: Repository): Promise<void> {
const worktreePicks = async (): Promise<WorktreeDeleteItem[] | QuickPickItem[]> => {
const worktrees = await repository.getWorktrees();
@@ -3894,6 +3846,21 @@ export class CommandCenter {
}
}
@command('git.deleteWorktree2', { repository: true, repositoryFilter: ['worktree'] })
async deleteWorktree(repository: Repository): Promise<void> {
if (!repository.dotGit.commonPath) {
return;
}
const mainRepository = this.model.getRepository(path.dirname(repository.dotGit.commonPath));
if (!mainRepository) {
await window.showErrorMessage(l10n.t('You cannot delete the worktree you are currently in. Please switch to the main repository first.'), { modal: true });
return;
}
await mainRepository.deleteWorktree(repository.root);
}
@command('git.openWorktree', { repository: true })
async openWorktreeInCurrentWindow(repository: Repository): Promise<void> {
if (!repository) {

View File

@@ -1171,16 +1171,6 @@ export class Model implements IRepositoryResolver, IBranchProtectionProviderRegi
}
}
disposeRepository(repository: Repository): void {
const openRepository = this.getOpenRepository(repository);
if (!openRepository) {
return;
}
this.logger.info(`[Model][disposeRepository] Repository: ${repository.root}`);
openRepository.dispose();
}
dispose(): void {
const openRepositories = [...this.openRepositories];
openRepositories.forEach(r => r.dispose());

View File

@@ -1802,7 +1802,33 @@ export class Repository implements Disposable {
}
async deleteWorktree(path: string, options?: { force?: boolean }): Promise<void> {
await this.run(Operation.DeleteWorktree, () => this.repository.deleteWorktree(path, options));
await this.run(Operation.DeleteWorktree, async () => {
const worktree = this.repositoryResolver.getRepository(path);
if (!worktree || worktree.kind !== 'worktree') {
return;
}
const deleteWorktree = async (options?: { force?: boolean }): Promise<void> => {
await this.repository.deleteWorktree(path, options);
worktree.dispose();
};
try {
await deleteWorktree();
} catch (err) {
if (err.gitErrorCode === GitErrorCodes.WorktreeContainsChanges) {
const forceDelete = l10n.t('Force Delete');
const message = l10n.t('The worktree contains modified or untracked files. Do you want to force delete?');
const choice = await window.showWarningMessage(message, { modal: true }, forceDelete);
if (choice === forceDelete) {
await deleteWorktree({ ...options, force: true });
}
return;
}
throw err;
}
});
}
async deleteRemoteRef(remoteName: string, refName: string, options?: { force?: boolean }): Promise<void> {