Skip to content

Commit

Permalink
feat: Enable user to create detached worktree
Browse files Browse the repository at this point in the history
  • Loading branch information
rbmarliere committed Sep 21, 2024
1 parent 314e334 commit 0f6da26
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 19 deletions.
27 changes: 16 additions & 11 deletions lua/git-worktree/git.lua
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ function M.has_branch(branch, opts, cb)
end

--- @param path string
--- @param branch string
--- @param branch string?
--- @param found_branch boolean
--- @param upstream string
--- @param found_upstream boolean
Expand All @@ -144,18 +144,23 @@ function M.create_worktree_job(path, branch, found_branch, upstream, found_upstr
local worktree_add_cmd = 'git'
local worktree_add_args = { 'worktree', 'add' }

if not found_branch then
table.insert(worktree_add_args, '-b')
table.insert(worktree_add_args, branch)
if branch == nil then
table.insert(worktree_add_args, '-d')
table.insert(worktree_add_args, path)

if found_upstream and branch ~= upstream then
table.insert(worktree_add_args, '--track')
table.insert(worktree_add_args, upstream)
end
else
table.insert(worktree_add_args, path)
table.insert(worktree_add_args, branch)
if not found_branch then
table.insert(worktree_add_args, '-b')
table.insert(worktree_add_args, branch)
table.insert(worktree_add_args, path)

if found_upstream and branch ~= upstream then
table.insert(worktree_add_args, '--track')
table.insert(worktree_add_args, upstream)
end
else
table.insert(worktree_add_args, path)
table.insert(worktree_add_args, branch)
end
end

return Job:new {
Expand Down
13 changes: 13 additions & 0 deletions lua/git-worktree/worktree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,19 @@ function M.create(path, branch, upstream)
return
end

if branch == '' then
-- detached head
local create_wt_job = Git.create_worktree_job(path, nil, false, nil, false)
create_wt_job:after(function()
vim.schedule(function()
Hooks.emit(Hooks.type.CREATE, path, branch, upstream)
M.switch(path)
end)
end)
create_wt_job:start()
return
end

Git.has_branch(branch, { '--remotes' }, function(found_remote_branch)
Log.debug('Found remote branch %s? %s', branch, found_remote_branch)
if found_remote_branch then
Expand Down
24 changes: 16 additions & 8 deletions lua/telescope/_extensions/git_worktree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ 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 Log = require('git-worktree.logger')

local force_next_deletion = false

Expand Down Expand Up @@ -91,9 +92,12 @@ end
local delete_success_handler = function(opts)
opts = opts or {}
force_next_deletion = false
if confirm_branch_deletion() and opts.branch ~= nil then
if opts.branch ~= nil and opts.branch ~= 'HEAD' and confirm_branch_deletion() then
local delete_branch_job = Git.delete_branch_job(opts.branch)
if delete_branch_job ~= nil then
delete_branch_job:after_success(vim.schedule_wrap(function()
print('Branch deleted')
end))
delete_branch_job:start()
end
end
Expand Down Expand Up @@ -134,6 +138,15 @@ local create_input_prompt = function(opts, cb)
opts.pattern = nil -- show all branches that can be tracked

local path = vim.fn.input('Path to subtree > ', opts.branch)
if path == '' then
Log.error("No worktree path provided")
return
end

if opts.branch == '' then
cb(path, nil)
return
end

local branches = vim.fn.systemlist('git branch --all')
if #branches == 0 then
Expand Down Expand Up @@ -173,17 +186,11 @@ local telescope_create_worktree = function(opts)
git_worktree.switch_worktree(nil)
opts = opts or {}

-- TODO: Enable detached HEAD worktree creation, but for this the telescope
-- picker git_branches must show refs/tags.

local create_branch = function(prompt_bufnr, _)
-- if current_line is still not enough to filter everything but user
-- still wants to use it as the new branch name, without selecting anything
local branch = action_state.get_current_line()
actions.close(prompt_bufnr)
if branch == nil then
return
end
opts.branch = branch
create_input_prompt(opts, function(path, upstream)
git_worktree.create_worktree(path, branch, upstream)
Expand All @@ -197,7 +204,8 @@ local telescope_create_worktree = function(opts)
-- selected_entry can be null if current_line filters everything
-- and there's no branch shown
local branch = selected_entry ~= nil and selected_entry.value or current_line
if branch == nil then
if branch == nil or branch == '' then
Log.error("No branch selected")
return
end
opts.branch = branch
Expand Down

0 comments on commit 0f6da26

Please sign in to comment.