After removing a nested worktree like feature/auth/oauth2, removes the
now-empty parent directories up to project root.
Assisted-by: Claude Opus 4.5 via Amp
@@ -32,6 +32,18 @@ local function get_bare_head(git_dir)
return (output:gsub("%s+$", ""))
end
+---Remove empty parent directories between target and project root
+---@param target_path string the removed worktree path
+---@param project_root string the project root (stop here)
+local function cleanup_empty_parents(target_path, project_root)
+ project_root = project_root:gsub("/$", "")
+ local parent = path_mod.parent_dir(target_path)
+ while parent and parent ~= project_root and path_mod.path_inside(parent, project_root) do
+ shell.run_cmd_silent("rmdir " .. shell.quote(parent))
+ parent = path_mod.parent_dir(parent)
+ end
+end
+
---Remove a worktree and optionally its branch
---@param args string[]
function M.cmd_remove(args)
@@ -106,6 +118,8 @@ function M.cmd_remove(args)
shell.die("failed to remove worktree: " .. output, exit.EXIT_SYSTEM_ERROR)
end
+ cleanup_empty_parents(target_path, root)
+
if delete_branch then
local bare_head = get_bare_head(git_dir)
if bare_head and bare_head == branch then
@@ -90,4 +90,13 @@ function M.escape_pattern(str)
return (str:gsub("([%%%-%+%[%]%(%)%.%^%$%*%?])", "%%%1"))
end
+---Get the parent directory of a path
+---@param path string
+---@return string|nil parent or nil if path has no parent
+function M.parent_dir(path)
+ path = path:gsub("/$", "")
+ local parent = path:match("(.+)/[^/]+$")
+ return parent
+end
+
return M