fix(git): reuse existing buffer instead of swallowing E95
This commit is contained in:
+22
-7
@@ -88,15 +88,20 @@ end
|
||||
---@param ref string the commit ref the blob represents (e.g. `<sha>` or `<sha>^`)
|
||||
---@return integer
|
||||
local function blob_buf(worktree, blob, path, ref)
|
||||
local name = "git://" .. ref .. "/" .. path
|
||||
-- Reuse an existing buffer with this name (commit refs and blobs are
|
||||
-- immutable, so the content is stable); avoids E95 collisions and
|
||||
-- prevents accumulating duplicate buffers as the user navigates.
|
||||
local existing = vim.fn.bufnr(name)
|
||||
if existing ~= -1 and vim.api.nvim_buf_is_loaded(existing) then
|
||||
return existing
|
||||
end
|
||||
if is_zero(blob) then
|
||||
return diff.empty_buf({
|
||||
name = "git://" .. ref .. "/" .. path,
|
||||
bufhidden = "hide",
|
||||
})
|
||||
return diff.empty_buf({ name = name, bufhidden = "hide" })
|
||||
end
|
||||
---@cast blob string
|
||||
local buf = diff.git_show_blob(worktree, blob)
|
||||
diff.set_buf_name_and_filetype(buf, "git://" .. ref .. "/" .. path)
|
||||
diff.set_buf_name_and_filetype(buf, name)
|
||||
return buf
|
||||
end
|
||||
|
||||
@@ -133,6 +138,17 @@ end
|
||||
---@param worktree string
|
||||
---@param ref string
|
||||
function M.open_commit(worktree, ref)
|
||||
local sha = repo.rev_parse(worktree, ref, true) or ref
|
||||
local name = "git://" .. sha .. "/"
|
||||
-- Reuse a previously-opened buffer for the same commit; commit SHAs
|
||||
-- are immutable so the content is stable.
|
||||
local existing = vim.fn.bufnr(name)
|
||||
if existing ~= -1 and vim.api.nvim_buf_is_loaded(existing) then
|
||||
vim.cmd("normal! m'")
|
||||
vim.cmd("buffer " .. existing)
|
||||
return
|
||||
end
|
||||
|
||||
local result = vim.system(
|
||||
{ "git", "show", ref },
|
||||
{ cwd = worktree, text = true }
|
||||
@@ -143,7 +159,6 @@ function M.open_commit(worktree, ref)
|
||||
return
|
||||
end
|
||||
local lines = util.split_lines(result.stdout or "")
|
||||
local sha = repo.rev_parse(worktree, ref, true) or ref
|
||||
local parent = repo.rev_parse(worktree, ref .. "^", true)
|
||||
local buf = vim.api.nvim_create_buf(false, true)
|
||||
vim.bo[buf].buftype = "nofile"
|
||||
@@ -152,7 +167,7 @@ function M.open_commit(worktree, ref)
|
||||
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
|
||||
vim.bo[buf].modifiable = false
|
||||
vim.bo[buf].modified = false
|
||||
pcall(vim.api.nvim_buf_set_name, buf, "git://" .. sha .. "/")
|
||||
pcall(vim.api.nvim_buf_set_name, buf, name)
|
||||
vim.b[buf].git_worktree = worktree
|
||||
vim.b[buf].git_ref = sha
|
||||
vim.b[buf].git_parent_ref = parent
|
||||
|
||||
Reference in New Issue
Block a user