Skip to content

Commit

Permalink
feat: Enable user to delete branch after deleting a worktree
Browse files Browse the repository at this point in the history
  • Loading branch information
rbmarliere committed Sep 19, 2024
1 parent a45a865 commit fe4c077
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 27 deletions.
52 changes: 52 additions & 0 deletions lua/git-worktree/git.lua
Original file line number Diff line number Diff line change
Expand Up @@ -251,4 +251,56 @@ function M.rebase_job(path)
}
end


--- @param path string
--- @return string|nil
function M.parse_head(path)
local job = Job:new {
command = 'git',
args = { 'rev-parse', '--abbrev-ref', 'HEAD' },
cwd = path,
on_start = function()
Log.debug('git rev-parse --abbrev-ref HEAD')
end,
}

local stdout, code = job:sync()
if code ~= 0 then
Log.error(
'Error in parsing the HEAD: code:'
.. tostring(code)
.. ' out: '
.. table.concat(stdout, '')
.. '.'
)
return nil
end

return table.concat(stdout, '')
end

--- @param branch string
--- @return Job|nil
function M.delete_branch_job(branch)
local root = M.gitroot_dir()
if root == nil then
return nil
end

local default = M.parse_head(root)
if default == branch then
print('Refusing to delete default branch')
return nil
end

return Job:new {
command = 'git',
args = { 'branch', '-D', branch },
cwd = M.gitroot_dir(),
on_start = function()
Log.debug('git branch -D')
end,
}
end

return M
4 changes: 3 additions & 1 deletion lua/git-worktree/worktree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ function M.delete(path, force, opts)
opts = {}
end

local branch = Git.parse_head(path)

Git.has_worktree(path, nil, function(found)
if not found then
Log.error('Worktree %s does not exist', path)
Expand All @@ -167,7 +169,7 @@ function M.delete(path, force, opts)
Log.info('delete after success')
Hooks.emit(Hooks.type.DELETE, path)
if opts.on_success then
opts.on_success()
opts.on_success({ branch = branch })
end
end))

Expand Down
67 changes: 41 additions & 26 deletions lua/telescope/_extensions/git_worktree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ local action_state = require('telescope.actions.state')
local conf = require('telescope.config').values
local git_worktree = require('git-worktree')
local Config = require('git-worktree.config')
local Git = require('git-worktree.git')

local force_next_deletion = false

Expand Down Expand Up @@ -49,53 +50,67 @@ local toggle_forced_deletion = function()
end
end

-- Handler for successful deletion
-- @return nil
local delete_success_handler = function()
print('Deleted worktree')
force_next_deletion = false
end

-- Handler for failed deletion
-- @return nil
local delete_failure_handler = function()
print('Deletion failed, use <C-f> to force the next deletion')
end

-- Ask the user to confirm the deletion of a worktree
-- Confirm the deletion of a worktree
-- @param forcing boolean: whether the deletion is forced
-- @return boolean: whether the deletion is confirmed
local ask_to_confirm_deletion = function(forcing)
local confirm_worktree_deletion = function(forcing)
if not Config.confirm_telescope_deletions then
return true
end

local confirmed = nil
if forcing then
return vim.fn.input('Force deletion of worktree? [y/n]: ')
confirmed = vim.fn.input('Force deletion of worktree? [y/n]: ')
else
confirmed = vim.fn.input('Delete worktree? [y/n]: ')
end

return vim.fn.input('Delete worktree? [y/n]: ')
if string.sub(string.lower(confirmed), 0, 1) == 'y' then
return true
end

print("Didn't delete worktree")
return false
end

-- Confirm the deletion of a worktree
-- @param forcing boolean: whether the deletion is forced
-- @return boolean: whether the deletion is confirmed
local confirm_deletion = function(forcing)
if not Config.confirm_telescope_deletions then
return true
end

local confirmed = ask_to_confirm_deletion(forcing)
local confirm_branch_deletion = function()
local confirmed = vim.fn.input('Worktree deleted, now force deletion of branch? [y/n]: ')

if string.sub(string.lower(confirmed), 0, 1) == 'y' then
return true
end

print("Didn't delete worktree")
print("Didn't delete branch")
return false
end

-- Handler for successful deletion
-- @return nil
local delete_success_handler = function(opts)
opts = opts or {}
force_next_deletion = false
if confirm_branch_deletion() and opts.branch ~= nil then
local delete_branch_job = Git.delete_branch_job(opts.branch)
if delete_branch_job ~= nil then
delete_branch_job:start()
end
end
end

-- Handler for failed deletion
-- @return nil
local delete_failure_handler = function()
print('Deletion failed, use <C-f> to force the next deletion')
end

-- Delete the selected worktree
-- @param prompt_bufnr number: the prompt buffer number
-- @return nil
local delete_worktree = function(prompt_bufnr)
if not confirm_deletion() then
-- TODO: confirm_deletion(forcing)
if not confirm_worktree_deletion() then
return
end

Expand Down

0 comments on commit fe4c077

Please sign in to comment.