diff --git a/lua/git/diff.lua b/lua/git/diff.lua index 3cceb8f..eedebbe 100644 --- a/lua/git/diff.lua +++ b/lua/git/diff.lua @@ -15,24 +15,23 @@ local function attach_index_writer(buf, worktree, path) vim.api.nvim_buf_get_lines(buf, 0, -1, false), "\n" ) .. "\n" - local hash = vim.system( + local hash_stdout = util.system_sync( { "git", "hash-object", "-w", "--stdin" }, - { cwd = worktree, stdin = body, text = true } - ):wait() - if hash.code ~= 0 then - log.error("git hash-object failed: %s", hash.stderr or "") + { cwd = worktree, stdin = body } + ) + if not hash_stdout then return end - local sha = vim.trim(hash.stdout or "") + local sha = vim.trim(hash_stdout) local mode = vim.b[buf].git_index_mode if not mode then mode = "100644" - local ls = vim.system( + local ls = util.system_sync( { "git", "ls-files", "-s", "--", path }, - { cwd = worktree, text = true } - ):wait() - if ls.code == 0 and ls.stdout then - local m = ls.stdout:match("^(%d+)") + { cwd = worktree, silent = true } + ) + if ls then + local m = ls:match("^(%d+)") if m then mode = m 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 -- (mode,sha,path), which doesn't survive paths containing a -- comma. - local upd = vim.system({ - "git", - "update-index", - "--cacheinfo", - mode, - sha, - path, - }, { cwd = worktree, text = true }):wait() - if upd.code ~= 0 then - log.error("git update-index failed: %s", upd.stderr or "") + if + not util.system_sync({ + "git", + "update-index", + "--cacheinfo", + mode, + sha, + path, + }, { cwd = worktree }) + then return end vim.bo[buf].modified = false @@ -105,25 +104,12 @@ function M.read_uri(buf) end local revspec = ref == "index" and (":" .. path) or (ref .. ":" .. path) - local result = vim.system( + local stdout = util.system_sync( { "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 if ref == "index" then diff --git a/lua/git/log.lua b/lua/git/log.lua index 29c80e9..9b680b5 100644 --- a/lua/git/log.lua +++ b/lua/git/log.lua @@ -38,22 +38,15 @@ function M.show(opts) table.insert(cmd, "--max-count=" .. max_count) end - local result = vim.system(cmd, { cwd = worktree, text = true }):wait() - if result.code ~= 0 then - log.error("git log failed: %s", vim.trim(result.stderr or "")) + local stdout = util.system_sync(cmd, { cwd = worktree }) + if not stdout then return end local buf = git.new_scratch() vim.b[buf].git_worktree = worktree vim.bo[buf].modifiable = true - vim.api.nvim_buf_set_lines( - buf, - 0, - -1, - false, - util.split_lines(result.stdout or "") - ) + 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 = "gitlog" diff --git a/lua/git/repo.lua b/lua/git/repo.lua index 659e53b..f62dc22 100644 --- a/lua/git/repo.lua +++ b/lua/git/repo.lua @@ -336,11 +336,8 @@ function M.rev_parse(worktree, ref, short) table.insert(cmd, "--short") end table.insert(cmd, ref) - local result = vim.system(cmd, { cwd = worktree, text = true }):wait() - if result.code ~= 0 then - return nil - end - local trimmed = vim.trim(result.stdout or "") + local stdout = util.system_sync(cmd, { cwd = worktree, silent = true }) + local trimmed = stdout and vim.trim(stdout) or "" return trimmed ~= "" and trimmed or nil end diff --git a/lua/git/show.lua b/lua/git/show.lua index 285bc5e..d3254b7 100644 --- a/lua/git/show.lua +++ b/lua/git/show.lua @@ -152,13 +152,8 @@ function M.open_commit(worktree, ref, opts) return end - local result = vim.system( - { "git", "show", ref }, - { cwd = worktree, text = true } - ) - :wait() - if result.code ~= 0 then - log.error("git show %s failed: %s", ref, vim.trim(result.stderr or "")) + local stdout = util.system_sync({ "git", "show", ref }, { cwd = worktree }) + if not stdout then return end @@ -168,13 +163,7 @@ function M.open_commit(worktree, ref, opts) 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(result.stdout or "") - ) + 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" diff --git a/lua/util.lua b/lua/util.lua index 39c3425..15e8637 100644 --- a/lua/util.lua +++ b/lua/util.lua @@ -441,4 +441,29 @@ function M.split_lines(content) return lines 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