refactor(git): consolidate sync subprocess pattern via util.system_sync

This commit is contained in:
2026-04-28 08:38:14 +02:00
parent d2633ae9c2
commit 4390b55dfe
5 changed files with 57 additions and 67 deletions
+18 -32
View File
@@ -15,24 +15,23 @@ local function attach_index_writer(buf, worktree, path)
vim.api.nvim_buf_get_lines(buf, 0, -1, false), vim.api.nvim_buf_get_lines(buf, 0, -1, false),
"\n" "\n"
) .. "\n" ) .. "\n"
local hash = vim.system( local hash_stdout = util.system_sync(
{ "git", "hash-object", "-w", "--stdin" }, { "git", "hash-object", "-w", "--stdin" },
{ cwd = worktree, stdin = body, text = true } { cwd = worktree, stdin = body }
):wait() )
if hash.code ~= 0 then if not hash_stdout then
log.error("git hash-object failed: %s", hash.stderr or "")
return return
end end
local sha = vim.trim(hash.stdout or "") local sha = vim.trim(hash_stdout)
local mode = vim.b[buf].git_index_mode local mode = vim.b[buf].git_index_mode
if not mode then if not mode then
mode = "100644" mode = "100644"
local ls = vim.system( local ls = util.system_sync(
{ "git", "ls-files", "-s", "--", path }, { "git", "ls-files", "-s", "--", path },
{ cwd = worktree, text = true } { cwd = worktree, silent = true }
):wait() )
if ls.code == 0 and ls.stdout then if ls then
local m = ls.stdout:match("^(%d+)") local m = ls:match("^(%d+)")
if m then if m then
mode = m mode = m
end end
@@ -42,16 +41,16 @@ local function attach_index_writer(buf, worktree, path)
-- Use the 3-arg form (mode sha path) instead of the comma form -- Use the 3-arg form (mode sha path) instead of the comma form
-- (mode,sha,path), which doesn't survive paths containing a -- (mode,sha,path), which doesn't survive paths containing a
-- comma. -- comma.
local upd = vim.system({ if
not util.system_sync({
"git", "git",
"update-index", "update-index",
"--cacheinfo", "--cacheinfo",
mode, mode,
sha, sha,
path, path,
}, { cwd = worktree, text = true }):wait() }, { cwd = worktree })
if upd.code ~= 0 then then
log.error("git update-index failed: %s", upd.stderr or "")
return return
end end
vim.bo[buf].modified = false vim.bo[buf].modified = false
@@ -105,25 +104,12 @@ function M.read_uri(buf)
end end
local revspec = ref == "index" and (":" .. path) or (ref .. ":" .. path) local revspec = ref == "index" and (":" .. path) or (ref .. ":" .. path)
local result = vim.system( local stdout = util.system_sync(
{ "git", "show", revspec }, { "git", "show", revspec },
{ cwd = worktree, text = true } { cwd = worktree }
)
:wait()
if result.code == 0 then
vim.api.nvim_buf_set_lines(
buf,
0,
-1,
false,
util.split_lines(result.stdout or "")
)
else
log.error(
"git show %s failed: %s",
revspec,
vim.trim(result.stderr or "")
) )
if stdout then
vim.api.nvim_buf_set_lines(buf, 0, -1, false, util.split_lines(stdout))
end end
if ref == "index" then if ref == "index" then
+3 -10
View File
@@ -38,22 +38,15 @@ function M.show(opts)
table.insert(cmd, "--max-count=" .. max_count) table.insert(cmd, "--max-count=" .. max_count)
end end
local result = vim.system(cmd, { cwd = worktree, text = true }):wait() local stdout = util.system_sync(cmd, { cwd = worktree })
if result.code ~= 0 then if not stdout then
log.error("git log failed: %s", vim.trim(result.stderr or ""))
return return
end end
local buf = git.new_scratch() local buf = git.new_scratch()
vim.b[buf].git_worktree = worktree vim.b[buf].git_worktree = worktree
vim.bo[buf].modifiable = true vim.bo[buf].modifiable = true
vim.api.nvim_buf_set_lines( vim.api.nvim_buf_set_lines(buf, 0, -1, false, util.split_lines(stdout))
buf,
0,
-1,
false,
util.split_lines(result.stdout or "")
)
vim.bo[buf].modifiable = false vim.bo[buf].modifiable = false
vim.bo[buf].modified = false vim.bo[buf].modified = false
vim.bo[buf].filetype = "gitlog" vim.bo[buf].filetype = "gitlog"
+2 -5
View File
@@ -336,11 +336,8 @@ function M.rev_parse(worktree, ref, short)
table.insert(cmd, "--short") table.insert(cmd, "--short")
end end
table.insert(cmd, ref) table.insert(cmd, ref)
local result = vim.system(cmd, { cwd = worktree, text = true }):wait() local stdout = util.system_sync(cmd, { cwd = worktree, silent = true })
if result.code ~= 0 then local trimmed = stdout and vim.trim(stdout) or ""
return nil
end
local trimmed = vim.trim(result.stdout or "")
return trimmed ~= "" and trimmed or nil return trimmed ~= "" and trimmed or nil
end end
+3 -14
View File
@@ -152,13 +152,8 @@ function M.open_commit(worktree, ref, opts)
return return
end end
local result = vim.system( local stdout = util.system_sync({ "git", "show", ref }, { cwd = worktree })
{ "git", "show", ref }, if not stdout then
{ cwd = worktree, text = true }
)
:wait()
if result.code ~= 0 then
log.error("git show %s failed: %s", ref, vim.trim(result.stderr or ""))
return return
end end
@@ -168,13 +163,7 @@ function M.open_commit(worktree, ref, opts)
vim.b[buf].git_ref = sha vim.b[buf].git_ref = sha
vim.b[buf].git_parent_ref = parent vim.b[buf].git_parent_ref = parent
vim.bo[buf].modifiable = true vim.bo[buf].modifiable = true
vim.api.nvim_buf_set_lines( vim.api.nvim_buf_set_lines(buf, 0, -1, false, util.split_lines(stdout))
buf,
0,
-1,
false,
util.split_lines(result.stdout or "")
)
vim.bo[buf].modifiable = false vim.bo[buf].modifiable = false
vim.bo[buf].modified = false vim.bo[buf].modified = false
vim.bo[buf].filetype = "git" vim.bo[buf].filetype = "git"
+25
View File
@@ -441,4 +441,29 @@ function M.split_lines(content)
return lines return lines
end end
---Run a system command synchronously and return stdout on success. On
---non-zero exit, logs stderr via `log.error` and returns nil. Pass
---`opts.silent` to suppress the auto-log when failure is expected (e.g.
---probe-style commands like `git rev-parse` against a possibly-missing
---ref).
---@param cmd string[]
---@param opts { cwd: string?, stdin: string?, silent: boolean? }?
---@return string?
function M.system_sync(cmd, opts)
opts = opts or {}
local result = vim.system(cmd, {
cwd = opts.cwd,
stdin = opts.stdin,
text = true,
}):wait()
if result.code ~= 0 then
if not opts.silent then
local label = cmd[2] and (cmd[1] .. " " .. cmd[2]) or cmd[1] or "?"
log.error("%s failed: %s", label, vim.trim(result.stderr or ""))
end
return nil
end
return result.stdout or ""
end
return M return M