mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-05 11:18:26 +00:00
fix(picker.git_branches): handle detached HEAD (#671)
## Description Handle [detached HEAD](https://git-scm.com/docs/git-checkout#_detached_head) - list: display correct information - preview: without error notification - action: checkout the commit that HEAD detached at <!-- Describe the big picture of your changes to communicate to the maintainers why we should accept this pull request. --> ## Related Issue(s) <!-- If this PR fixes any issues, please link to the issue here. - Fixes #<issue_number> --> - Fixes #672 ## Screenshots <!-- Add screenshots of the changes if applicable. --> Before: <img width="1308" alt="image" src="https://github.com/user-attachments/assets/fad291a3-a730-4a2b-9eb2-4a0edd83d794" /> After: <img width="1038" alt="image" src="https://github.com/user-attachments/assets/d312579a-e12d-4286-845c-a706d91a6c95" /> --------- Co-authored-by: Folke Lemaitre <folke.lemaitre@gmail.com>
This commit is contained in:
parent
a1c78a2459
commit
390f687431
4 changed files with 32 additions and 8 deletions
|
@ -49,6 +49,7 @@ Snacks.util.set_hl({
|
|||
UndoSaved = "Special",
|
||||
GitCommit = "@variable.builtin",
|
||||
GitBreaking = "Error",
|
||||
GitDetached = "DiagnosticWarn",
|
||||
GitBranch = "Title",
|
||||
GitBranchCurrent = "Number",
|
||||
GitDate = "Special",
|
||||
|
|
|
@ -138,9 +138,12 @@ function M.git_branch(item, picker)
|
|||
local ret = {} ---@type snacks.picker.Highlight[]
|
||||
if item.current then
|
||||
ret[#ret + 1] = { a("", 2), "SnacksPickerGitBranchCurrent" }
|
||||
ret[#ret + 1] = { a(item.branch, 30, { truncate = true }), "SnacksPickerGitBranch" }
|
||||
else
|
||||
ret[#ret + 1] = { a("", 2) }
|
||||
end
|
||||
if item.detached then
|
||||
ret[#ret + 1] = { a("(detached HEAD)", 30, { truncate = true }), "SnacksPickerGitDetached" }
|
||||
else
|
||||
ret[#ret + 1] = { a(item.branch, 30, { truncate = true }), "SnacksPickerGitBranch" }
|
||||
end
|
||||
ret[#ret + 1] = { " " }
|
||||
|
|
|
@ -192,7 +192,7 @@ function M.cmd(cmd, ctx, opts)
|
|||
if not killed and code ~= 0 then
|
||||
Snacks.notify.error(
|
||||
("Terminal **cmd** `%s` failed with code `%d`:\n- `vim.o.shell = %q`\n\nOutput:\n%s"):format(
|
||||
cmd,
|
||||
type(cmd) == "table" and table.concat(cmd, " ") or cmd,
|
||||
code,
|
||||
vim.o.shell,
|
||||
vim.trim(table.concat(output, ""))
|
||||
|
@ -254,7 +254,7 @@ function M.git_log(ctx)
|
|||
"--color=never",
|
||||
"--no-show-signature",
|
||||
"--no-patch",
|
||||
ctx.item.branch,
|
||||
ctx.item.commit,
|
||||
}
|
||||
if not native then
|
||||
table.insert(cmd, 2, "--no-pager")
|
||||
|
|
|
@ -163,18 +163,38 @@ function M.branches(opts)
|
|||
local args = { "--no-pager", "branch", "--no-color", "-vvl" }
|
||||
local cwd = vim.fs.normalize(opts and opts.cwd or uv.cwd() or ".") or nil
|
||||
cwd = Snacks.git.get_root(cwd)
|
||||
|
||||
local pattern_hash = "[a-zA-Z0-9]+"
|
||||
local patterns = {
|
||||
-- stylua: ignore start
|
||||
--- e.g. "* (HEAD detached at f65a2c8) f65a2c8 chore(build): auto-generate docs"
|
||||
"^(.)%s(%(HEAD detached at " .. pattern_hash .. "%))%s+(" .. pattern_hash .. ")%s*(.*)$",
|
||||
--- e.g. " main d2b2b7b [origin/main: behind 276] chore(build): auto-generate docs"
|
||||
"^(.)%s(%S+)%s+(".. pattern_hash .. ")%s*(.*)$",
|
||||
-- stylua: ignore end
|
||||
} ---@type string[]
|
||||
|
||||
return require("snacks.picker.source.proc").proc(vim.tbl_deep_extend("force", {
|
||||
cwd = cwd,
|
||||
cmd = "git",
|
||||
args = args,
|
||||
---@param item snacks.picker.finder.Item
|
||||
transform = function(item)
|
||||
local status, branch, commit, msg = item.text:match("^(.)%s(%S+)%s+([a-zA-Z0-9]+)%s*(.*)$")
|
||||
item.cwd = cwd
|
||||
item.current = status == "*"
|
||||
item.branch = branch
|
||||
item.commit = commit
|
||||
item.msg = msg
|
||||
for p, pattern in ipairs(patterns) do
|
||||
local status, branch, commit, msg = item.text:match(pattern)
|
||||
if status then
|
||||
local detached = p == 1
|
||||
item.current = status == "*"
|
||||
item.branch = not detached and branch or nil
|
||||
item.commit = commit
|
||||
item.msg = msg
|
||||
item.detached = detached
|
||||
return
|
||||
end
|
||||
end
|
||||
Snacks.notify.warn("failed to parse branch: " .. item.text)
|
||||
return false -- skip items we could not parse
|
||||
end,
|
||||
}, opts or {}))
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue