perf(git): fold revspec validation into the cat-file -p the loader needs anyway
This commit is contained in:
+19
-8
@@ -157,13 +157,17 @@ local function uri_split(opts, cur_buf, cur_revspec)
|
|||||||
local cur_writable = cur.stage == 0
|
local cur_writable = cur.stage == 0
|
||||||
|
|
||||||
if opts.revspec ~= "" and opts.revspec:find(":", 1, true) then
|
if opts.revspec ~= "" and opts.revspec:find(":", 1, true) then
|
||||||
if not repo.object_exists(worktree, opts.revspec) then
|
local content = util.exec(
|
||||||
|
{ "git", "cat-file", "-p", opts.revspec },
|
||||||
|
{ cwd = worktree, silent = true }
|
||||||
|
)
|
||||||
|
if not content then
|
||||||
util.warning("invalid revspec: %s", opts.revspec)
|
util.warning("invalid revspec: %s", opts.revspec)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
place_pair(
|
place_pair(
|
||||||
cur_buf,
|
cur_buf,
|
||||||
object.buf_for(worktree, opts.revspec),
|
object.buf_for(worktree, opts.revspec, content),
|
||||||
cur_writable,
|
cur_writable,
|
||||||
opts.vertical
|
opts.vertical
|
||||||
)
|
)
|
||||||
@@ -192,13 +196,17 @@ local function uri_split(opts, cur_buf, cur_revspec)
|
|||||||
else
|
else
|
||||||
other_revspec = ":0:" .. cur.path
|
other_revspec = ":0:" .. cur.path
|
||||||
end
|
end
|
||||||
if not repo.object_exists(worktree, other_revspec) then
|
local content = util.exec(
|
||||||
|
{ "git", "cat-file", "-p", other_revspec },
|
||||||
|
{ cwd = worktree, silent = true }
|
||||||
|
)
|
||||||
|
if not content then
|
||||||
util.warning("invalid revspec: %s", other_revspec)
|
util.warning("invalid revspec: %s", other_revspec)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
place_pair(
|
place_pair(
|
||||||
cur_buf,
|
cur_buf,
|
||||||
object.buf_for(worktree, other_revspec),
|
object.buf_for(worktree, other_revspec, content),
|
||||||
cur.stage ~= nil,
|
cur.stage ~= nil,
|
||||||
opts.vertical
|
opts.vertical
|
||||||
)
|
)
|
||||||
@@ -248,13 +256,16 @@ function M.split(opts)
|
|||||||
else
|
else
|
||||||
revspec = opts.revspec .. ":" .. rel
|
revspec = opts.revspec .. ":" .. rel
|
||||||
end
|
end
|
||||||
if not repo.object_exists(worktree, revspec) then
|
local content = util.exec(
|
||||||
|
{ "git", "cat-file", "-p", revspec },
|
||||||
|
{ cwd = worktree, silent = true }
|
||||||
|
)
|
||||||
|
if not content then
|
||||||
util.warning("invalid revspec: %s", revspec)
|
util.warning("invalid revspec: %s", revspec)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local buf = vim.fn.bufadd("git://" .. revspec)
|
local object = require("git.object")
|
||||||
vim.b[buf].git_worktree = worktree
|
local buf = object.buf_for(worktree, revspec, content)
|
||||||
|
|
||||||
local other_writable = util.parse_revspec(revspec).stage == 0
|
local other_writable = util.parse_revspec(revspec).stage == 0
|
||||||
place_pair(buf, cur_buf, other_writable, opts.vertical)
|
place_pair(buf, cur_buf, other_writable, opts.vertical)
|
||||||
end
|
end
|
||||||
|
|||||||
+20
-3
@@ -135,16 +135,29 @@ local function attach_index_writer(buf, worktree, path)
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Pre-fetched content keyed by bufnr. Set by `buf_for(_, _, content)`
|
||||||
|
---and consumed by the next `read_uri` dispatch on that buffer. Lets
|
||||||
|
---callers fold validation + content fetch + buffer load into one
|
||||||
|
---`cat-file` call instead of preflighting separately.
|
||||||
|
---@type table<integer, string>
|
||||||
|
local pending_content = {}
|
||||||
|
|
||||||
---Return a buffer holding the content addressed by a git revspec. The
|
---Return a buffer holding the content addressed by a git revspec. The
|
||||||
---URI is `git://<revspec>` and BufReadCmd routes through `M.read_uri`,
|
---URI is `git://<revspec>` and BufReadCmd routes through `M.read_uri`,
|
||||||
---which loads via `git cat-file -p`.
|
---which loads via `git cat-file -p`. If `content` is given, primes a
|
||||||
|
---cache so the BufReadCmd handler reuses it instead of running another
|
||||||
|
---`cat-file -p`.
|
||||||
---@param worktree string
|
---@param worktree string
|
||||||
---@param revspec string any revspec git understands (e.g. `HEAD:foo`, `:foo`, `:1:foo`, `<sha>`, `<sha>:foo`)
|
---@param revspec string any revspec git understands (e.g. `HEAD:foo`, `:foo`, `:1:foo`, `<sha>`, `<sha>:foo`)
|
||||||
|
---@param content string?
|
||||||
---@return integer
|
---@return integer
|
||||||
function M.buf_for(worktree, revspec)
|
function M.buf_for(worktree, revspec, content)
|
||||||
local name = "git://" .. revspec
|
local name = "git://" .. revspec
|
||||||
local buf = vim.fn.bufadd(name)
|
local buf = vim.fn.bufadd(name)
|
||||||
vim.b[buf].git_worktree = worktree
|
vim.b[buf].git_worktree = worktree
|
||||||
|
if content then
|
||||||
|
pending_content[buf] = content
|
||||||
|
end
|
||||||
vim.fn.bufload(buf)
|
vim.fn.bufload(buf)
|
||||||
return buf
|
return buf
|
||||||
end
|
end
|
||||||
@@ -172,10 +185,14 @@ function M.read_uri(buf)
|
|||||||
vim.bo[buf].swapfile = false
|
vim.bo[buf].swapfile = false
|
||||||
vim.bo[buf].bufhidden = "wipe"
|
vim.bo[buf].bufhidden = "wipe"
|
||||||
|
|
||||||
local stdout = util.exec(
|
local stdout = pending_content[buf]
|
||||||
|
pending_content[buf] = nil
|
||||||
|
if stdout == nil then
|
||||||
|
stdout = util.exec(
|
||||||
{ "git", "cat-file", "-p", revspec },
|
{ "git", "cat-file", "-p", revspec },
|
||||||
{ cwd = worktree }
|
{ cwd = worktree }
|
||||||
)
|
)
|
||||||
|
end
|
||||||
if stdout then
|
if stdout then
|
||||||
vim.api.nvim_buf_set_lines(buf, 0, -1, false, util.split_lines(stdout))
|
vim.api.nvim_buf_set_lines(buf, 0, -1, false, util.split_lines(stdout))
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -343,18 +343,4 @@ function M.rev_parse(worktree, ref, short)
|
|||||||
return trimmed ~= "" and trimmed or nil
|
return trimmed ~= "" and trimmed or nil
|
||||||
end
|
end
|
||||||
|
|
||||||
---Verify a revspec resolves to an existing git object. `cat-file -e` is
|
|
||||||
---git's cheapest existence check, and unlike `rev-parse --verify` it
|
|
||||||
---also accepts the `<commit>:<path>` form that BufReadCmd revspec URIs
|
|
||||||
---use.
|
|
||||||
---@param worktree string
|
|
||||||
---@param revspec string
|
|
||||||
---@return boolean
|
|
||||||
function M.object_exists(worktree, revspec)
|
|
||||||
return util.exec(
|
|
||||||
{ "git", "cat-file", "-e", revspec },
|
|
||||||
{ cwd = worktree, silent = true }
|
|
||||||
) ~= nil
|
|
||||||
end
|
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
Reference in New Issue
Block a user