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 ` output in a buffer (indented message, ---unified-diff body). For the navigable raw-object form used by the ---gitlog `` 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