From dea40351e4fd5d6ffe819963c0cdf112651d4d0f Mon Sep 17 00:00:00 2001 From: Bert Verhelst Date: Thu, 22 Oct 2026 08:15:16 +0200 Subject: [PATCH 1/2] feature: add option to delete worktrees when deleting a local branch Co-Authored-By: Claude Opus 5.5 --- src/Resources/Locales/en_US.axaml | 1 + src/ViewModels/DeleteBranch.cs | 42 +++++++++++++++++++++++++++++++ src/Views/DeleteBranch.axaml | 11 ++++++-- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index d3ffb203a4..1dd554e856 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -348,6 +348,7 @@ Submodule: Delete Branch Branch: + Delete worktrees for this branch Force delete even if it contains unmerged commit(s) You are about to delete a remote branch!!! Also delete remote branch ${0}$ diff --git a/src/ViewModels/DeleteBranch.cs b/src/ViewModels/DeleteBranch.cs index 483f321dde..db2e3be15d 100644 --- a/src/ViewModels/DeleteBranch.cs +++ b/src/ViewModels/DeleteBranch.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; namespace SourceGit.ViewModels @@ -32,6 +33,22 @@ public bool Force set; } + public List AttachedWorktrees + { + get; + } = []; + + public bool HasAttachedWorktrees + { + get => AttachedWorktrees.Count > 0; + } + + public bool DeleteWorktrees + { + get; + set; + } + public DeleteBranch(Repository repo, Models.Branch branch) { _repo = repo; @@ -46,6 +63,15 @@ public DeleteBranch(Repository repo, Models.Branch branch) DeleteUpstreamTip = App.Text("DeleteBranch.WithTrackingRemote", upstream.FriendlyName); } } + + if (branch.IsLocal) + { + foreach (var wt in _repo.Worktrees) + { + if (!wt.IsMain && !wt.IsCurrent && wt.Backend.Branch.Equals(branch.FullName, StringComparison.Ordinal)) + AttachedWorktrees.Add(wt); + } + } } public override async Task Sure() @@ -61,6 +87,22 @@ public override async Task Sure() { do { + if (DeleteWorktrees) + { + foreach (var wt in AttachedWorktrees) + { + succ = await new Commands.Worktree(_repo.FullPath) + .Use(log) + .RemoveAsync(wt.FullPath, Force); + + if (!succ) + break; + } + + if (!succ) + break; + } + succ = await new Commands.Branch(_repo.FullPath, Target.Name) .Use(log) .DeleteLocalAsync(Force); diff --git a/src/Views/DeleteBranch.axaml b/src/Views/DeleteBranch.axaml index d27b11ea78..e9c0b4bfdf 100644 --- a/src/Views/DeleteBranch.axaml +++ b/src/Views/DeleteBranch.axaml @@ -18,7 +18,7 @@ Text="{DynamicResource Text.DeleteBranch}"/> - + @@ -55,7 +55,14 @@ - + + + + From f8f48f5a769c5c15ae841ea4ad03470c3968c23c Mon Sep 17 00:00:00 2001 From: Bert Verhelst Date: Thu, 22 Oct 2026 08:20:18 +0200 Subject: [PATCH 2/2] fix: skip worktrees that were already removed when deleting a branch Co-Authored-By: Claude Opus 5.5 --- src/ViewModels/DeleteBranch.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ViewModels/DeleteBranch.cs b/src/ViewModels/DeleteBranch.cs index db2e3be15d..12b0b49c28 100644 --- a/src/ViewModels/DeleteBranch.cs +++ b/src/ViewModels/DeleteBranch.cs @@ -89,8 +89,14 @@ public override async Task Sure() { if (DeleteWorktrees) { + // Re-read worktrees, since a previous (failed) attempt may have already removed some of them. + succ = true; + var current = await new Commands.Worktree(_repo.FullPath).ReadAllAsync(); foreach (var wt in AttachedWorktrees) { + if (!current.Exists(x => x.FullPath.Equals(wt.FullPath, StringComparison.Ordinal))) + continue; + succ = await new Commands.Worktree(_repo.FullPath) .Use(log) .RemoveAsync(wt.FullPath, Force);