53 lines
1.8 KiB
Lua
53 lines
1.8 KiB
Lua
local git = require("git")
|
|
local repo = require("git.repo")
|
|
local util = require("git.util")
|
|
|
|
local M = {}
|
|
|
|
---@class ow.Git.ShowOpts
|
|
---@field split (false|"above"|"below"|"left"|"right")? forwarded to `git.new_scratch`. Default opens a new horizontal split.
|
|
|
|
---Open a commit's `git show <ref>` output in a buffer (indented message,
|
|
---unified-diff body). For the navigable raw-object form used by the
|
|
---gitlog `<CR>` flow, see `git.object` `M.open_commit`.
|
|
---@param worktree string
|
|
---@param ref string
|
|
---@param opts ow.Git.ShowOpts?
|
|
function M.show(worktree, ref, opts)
|
|
local split = opts and opts.split
|
|
local sha = repo.rev_parse(worktree, ref, true) or ref
|
|
local name = "git://" .. sha
|
|
-- Commit SHAs are immutable so a previously-opened buffer is still
|
|
-- valid. Reuse it instead of refetching.
|
|
local existing = vim.fn.bufnr(name)
|
|
if existing ~= -1 and vim.api.nvim_buf_is_loaded(existing) then
|
|
if split == false then
|
|
vim.cmd.normal({ "m'", bang = true })
|
|
vim.api.nvim_set_current_buf(existing)
|
|
else
|
|
vim.api.nvim_open_win(existing, true, {
|
|
split = split or (vim.o.splitbelow and "below" or "above"),
|
|
})
|
|
end
|
|
return
|
|
end
|
|
|
|
local stdout = util.exec({ "git", "show", ref }, { cwd = worktree })
|
|
if not stdout then
|
|
return
|
|
end
|
|
|
|
local parent = repo.rev_parse(worktree, ref .. "^", true)
|
|
local buf, _ = git.new_scratch({ name = name, split = split })
|
|
vim.b[buf].git_worktree = worktree
|
|
vim.b[buf].git_ref = sha
|
|
vim.b[buf].git_parent_ref = parent
|
|
vim.bo[buf].modifiable = true
|
|
vim.api.nvim_buf_set_lines(buf, 0, -1, false, util.split_lines(stdout))
|
|
vim.bo[buf].modifiable = false
|
|
vim.bo[buf].modified = false
|
|
vim.bo[buf].filetype = "git"
|
|
end
|
|
|
|
return M
|