Skip to content

Commit 6def0bc

Browse files
committed
Add --force / -f option for --prune and --remove
Force removes worktrees with dirty/untracked changes and force deletes local branches. Also switches git branch flags from short (-d/-D) to long form (--delete/--delete --force) for readability.
1 parent a27a5ce commit 6def0bc

2 files changed

Lines changed: 31 additions & 11 deletions

File tree

src/git-wt/Commands.cs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ public static int List()
217217
/// <summary>
218218
/// Removes a specific worktree and its local branch.
219219
/// </summary>
220-
public static int Remove(string branchName)
220+
public static int Remove(string branchName, bool force = false)
221221
{
222222
if (!TryFindBareRepo(out var bareRepoPath, out var repoRoot))
223223
return 1;
@@ -238,14 +238,20 @@ public static int Remove(string branchName)
238238
}
239239

240240
Console.WriteLine($"Removing worktree '{branchName}'...");
241-
if (Git.RunLive(bareRepoPath, "worktree", "remove", match.Path) != 0)
241+
var removeArgs = force
242+
? new[] { "worktree", "remove", "--force", match.Path }
243+
: new[] { "worktree", "remove", match.Path };
244+
if (Git.RunLive(bareRepoPath, removeArgs) != 0)
242245
{
243246
Console.Error.WriteLine("Error: Failed to remove worktree. It may have dirty or untracked changes.");
244-
Console.Error.WriteLine("Use 'git worktree remove --force' to remove it anyway.");
247+
Console.Error.WriteLine("Use --force to remove it anyway.");
245248
return 1;
246249
}
247250

248-
var (delExit, _, _) = Git.Run(bareRepoPath, "branch", "-d", branchName);
251+
var deleteArgs = force
252+
? new[] { "branch", "--delete", "--force", branchName }
253+
: new[] { "branch", "--delete", branchName };
254+
var (delExit, _, _) = Git.Run(bareRepoPath, deleteArgs);
249255
if (delExit != 0)
250256
Console.Error.WriteLine($"Warning: Could not delete branch '{branchName}'. Remove manually with: git branch -D {branchName}");
251257

@@ -259,7 +265,7 @@ public static int Remove(string branchName)
259265
/// Removes worktrees whose upstream branch has been deleted (gone),
260266
/// then cleans up empty parent directories.
261267
/// </summary>
262-
public static int Prune()
268+
public static int Prune(bool force = false)
263269
{
264270
if (!TryFindBareRepo(out var bareRepoPath, out var repoRoot))
265271
return 1;
@@ -304,22 +310,28 @@ public static int Prune()
304310
foreach (var (wtPath, branch) in goneBranches)
305311
{
306312
Console.WriteLine($"Removing worktree '{branch}'...");
307-
if (Git.RunLive(bareRepoPath, "worktree", "remove", wtPath) != 0)
313+
var removeArgs = force
314+
? new[] { "worktree", "remove", "--force", wtPath }
315+
: new[] { "worktree", "remove", wtPath };
316+
if (Git.RunLive(bareRepoPath, removeArgs) != 0)
308317
{
309-
Console.Error.WriteLine($" Skipped: worktree has dirty or untracked changes.");
318+
Console.Error.WriteLine($" Skipped: could not remove worktree.");
310319
failed++;
311320
continue;
312321
}
313322

314-
var (delExit, _, _) = Git.Run(bareRepoPath, "branch", "-d", branch);
323+
var deleteArgs = force
324+
? new[] { "branch", "--delete", "--force", branch }
325+
: new[] { "branch", "--delete", branch };
326+
var (delExit, _, _) = Git.Run(bareRepoPath, deleteArgs);
315327
if (delExit != 0)
316328
Console.Error.WriteLine($" Warning: Could not delete branch '{branch}'. Remove manually with: git branch -D {branch}");
317329

318330
RemoveEmptyParentDirectories(wtPath, repoRoot);
319331
}
320332

321333
var removed = goneBranches.Count - failed;
322-
Console.WriteLine($"Pruned {removed} worktree{(removed == 1 ? "" : "s")}{(failed > 0 ? $", {failed} skipped (dirty)" : "")}.");
334+
Console.WriteLine($"Pruned {removed} worktree{(removed == 1 ? "" : "s")}{(failed > 0 ? $", {failed} skipped" : "")}.");
323335
return 0;
324336
}
325337

src/git-wt/Program.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
Description = "Clone a repository into a bare worktree layout: <name>/.bare + default branch worktree"
2727
};
2828

29+
var forceOption = new Option<bool>("--force", "-f")
30+
{
31+
Description = "Force remove worktrees with dirty/untracked changes and force delete local branches (use with --prune or --remove)"
32+
};
33+
2934
var colorOption = new Option<bool>("--color")
3035
{
3136
Description = "Force colored output even when piped"
@@ -43,6 +48,7 @@
4348
pruneOption,
4449
removeOption,
4550
setupOption,
51+
forceOption,
4652
colorOption,
4753
noColorOption
4854
};
@@ -58,12 +64,14 @@
5864
if (parseResult.GetValue(listOption))
5965
return Commands.List();
6066

67+
var force = parseResult.GetValue(forceOption);
68+
6169
if (parseResult.GetValue(pruneOption))
62-
return Commands.Prune();
70+
return Commands.Prune(force);
6371

6472
var removeBranch = parseResult.GetValue(removeOption);
6573
if (!string.IsNullOrEmpty(removeBranch))
66-
return Commands.Remove(removeBranch);
74+
return Commands.Remove(removeBranch, force);
6775

6876
var branchName = parseResult.GetValue(branchArg);
6977
if (string.IsNullOrEmpty(branchName))

0 commit comments

Comments
 (0)