refactor(git): route every git invocation through util.git
This commit is contained in:
+33
-38
@@ -22,17 +22,12 @@ local function git_cmds()
|
||||
if cached_cmds then
|
||||
return cached_cmds
|
||||
end
|
||||
local result = vim.system(
|
||||
{ "git", "--list-cmds=main,others,alias" },
|
||||
{ text = true }
|
||||
)
|
||||
:wait()
|
||||
if result.code ~= 0 then
|
||||
util.error("git --list-cmds failed: %s", vim.trim(result.stderr or ""))
|
||||
local out = util.git({ "--list-cmds=main,others,alias" })
|
||||
if not out then
|
||||
return {}
|
||||
end
|
||||
cached_cmds = {}
|
||||
for line in (result.stdout or ""):gmatch("[^\r\n]+") do
|
||||
for line in out:gmatch("[^\r\n]+") do
|
||||
if line ~= "" then
|
||||
table.insert(cached_cmds, line)
|
||||
end
|
||||
@@ -191,10 +186,16 @@ end
|
||||
local function run_in_split(r, args, conf)
|
||||
util.git(args, {
|
||||
cwd = r.worktree,
|
||||
on_done = function(stdout)
|
||||
if not stdout then
|
||||
on_exit = function(result)
|
||||
if result.code ~= 0 then
|
||||
util.error(
|
||||
"git %s failed: %s",
|
||||
args[1] or "?",
|
||||
vim.trim(result.stderr or "")
|
||||
)
|
||||
return
|
||||
end
|
||||
local stdout = result.stdout or ""
|
||||
local buf = place_split("[Git " .. table.concat(args, " ") .. "]")
|
||||
repo.bind(buf, r)
|
||||
object.attach_dispatch(buf)
|
||||
@@ -216,14 +217,11 @@ end
|
||||
---@param r ow.Git.Repo
|
||||
---@param args string[]
|
||||
local function run_to_messages(r, args)
|
||||
local cmd = { "git" }
|
||||
vim.list_extend(cmd, args)
|
||||
vim.system(
|
||||
cmd,
|
||||
{ cwd = r.worktree, text = true },
|
||||
vim.schedule_wrap(function(obj)
|
||||
local out = vim.trim(obj.stdout or "")
|
||||
local err = vim.trim(obj.stderr or "")
|
||||
util.git(args, {
|
||||
cwd = r.worktree,
|
||||
on_exit = function(result)
|
||||
local out = vim.trim(result.stdout or "")
|
||||
local err = vim.trim(result.stderr or "")
|
||||
local chunks = {}
|
||||
if out ~= "" then
|
||||
table.insert(chunks, { out })
|
||||
@@ -234,17 +232,17 @@ local function run_to_messages(r, args)
|
||||
end
|
||||
table.insert(chunks, { err, "ErrorMsg" })
|
||||
end
|
||||
if #chunks == 0 and obj.code ~= 0 then
|
||||
if #chunks == 0 and result.code ~= 0 then
|
||||
table.insert(
|
||||
chunks,
|
||||
{ "git exited " .. tostring(obj.code), "ErrorMsg" }
|
||||
{ "git exited " .. tostring(result.code), "ErrorMsg" }
|
||||
)
|
||||
end
|
||||
if #chunks > 0 then
|
||||
vim.api.nvim_echo(chunks, true, {})
|
||||
end
|
||||
end)
|
||||
)
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
---@param args string[]
|
||||
@@ -337,11 +335,11 @@ end
|
||||
---@return string[]
|
||||
local function list_files(r, dir)
|
||||
return r:get_cached("files:" .. dir, function(self)
|
||||
local cmd = { "git", "ls-files" }
|
||||
local args = { "ls-files" }
|
||||
if dir ~= "" then
|
||||
table.insert(cmd, dir)
|
||||
table.insert(args, dir)
|
||||
end
|
||||
local out = util.exec(cmd, { cwd = self.worktree, silent = true })
|
||||
local out = util.git(args, { cwd = self.worktree, silent = true })
|
||||
return out and util.split_lines(out) or {}
|
||||
end)
|
||||
end
|
||||
@@ -350,8 +348,8 @@ end
|
||||
---@return string[]
|
||||
local function list_remotes(r)
|
||||
return r:get_cached("remotes", function(self)
|
||||
local out = util.exec(
|
||||
{ "git", "remote" },
|
||||
local out = util.git(
|
||||
{ "remote" },
|
||||
{ cwd = self.worktree, silent = true }
|
||||
)
|
||||
return out and util.split_lines(out) or {}
|
||||
@@ -382,13 +380,10 @@ local function fetch_completions(sub)
|
||||
if cached_completions[sub] then
|
||||
return cached_completions[sub]
|
||||
end
|
||||
local out = util.exec(
|
||||
{ "git", sub, "--git-completion-helper-all" },
|
||||
local out = util.git(
|
||||
{ sub, "--git-completion-helper-all" },
|
||||
{ silent = true }
|
||||
) or util.exec(
|
||||
{ "git", sub, "--git-completion-helper" },
|
||||
{ silent = true }
|
||||
)
|
||||
) or util.git({ sub, "--git-completion-helper" }, { silent = true })
|
||||
local items = {}
|
||||
if out then
|
||||
for tok in out:gmatch("%S+") do
|
||||
@@ -469,8 +464,8 @@ function M.complete_rev(arg_lead)
|
||||
|
||||
local stage, stage_path_lead = arg_lead:match("^:([0-3]):(.*)$")
|
||||
if stage then
|
||||
local out = util.exec(
|
||||
{ "git", "ls-files", "--stage" },
|
||||
local out = util.git(
|
||||
{ "ls-files", "--stage" },
|
||||
{ cwd = r.worktree, silent = true }
|
||||
)
|
||||
if not out then
|
||||
@@ -506,11 +501,11 @@ function M.complete_rev(arg_lead)
|
||||
name_lead = name_lead or path_lead
|
||||
|
||||
if rev ~= "" then
|
||||
local cmd = { "git", "ls-tree", rev }
|
||||
local args = { "ls-tree", rev }
|
||||
if dir ~= "" then
|
||||
table.insert(cmd, dir)
|
||||
table.insert(args, dir)
|
||||
end
|
||||
local out = util.exec(cmd, { cwd = r.worktree, silent = true })
|
||||
local out = util.git(args, { cwd = r.worktree, silent = true })
|
||||
if not out then
|
||||
return {}
|
||||
end
|
||||
|
||||
@@ -32,8 +32,7 @@ end
|
||||
---@param max_count integer?
|
||||
---@return string?
|
||||
local function fetch(worktree, max_count)
|
||||
local cmd = {
|
||||
"git",
|
||||
local args = {
|
||||
"log",
|
||||
"--graph",
|
||||
"--all",
|
||||
@@ -42,9 +41,9 @@ local function fetch(worktree, max_count)
|
||||
"--format=format:" .. LOG_FORMAT,
|
||||
}
|
||||
if max_count then
|
||||
table.insert(cmd, "--max-count=" .. max_count)
|
||||
table.insert(args, "--max-count=" .. max_count)
|
||||
end
|
||||
return util.exec(cmd, { cwd = worktree })
|
||||
return util.git(args, { cwd = worktree })
|
||||
end
|
||||
|
||||
---@type table<string, integer> -- worktree -> max_count
|
||||
|
||||
+7
-8
@@ -96,8 +96,8 @@ local function attach_index_writer(buf, r, path)
|
||||
vim.api.nvim_buf_get_lines(buf, 0, -1, false),
|
||||
"\n"
|
||||
) .. "\n"
|
||||
local hash_stdout = util.exec(
|
||||
{ "git", "hash-object", "-w", "--stdin" },
|
||||
local hash_stdout = util.git(
|
||||
{ "hash-object", "-w", "--stdin" },
|
||||
{ cwd = r.worktree, stdin = body }
|
||||
)
|
||||
if not hash_stdout then
|
||||
@@ -108,8 +108,8 @@ local function attach_index_writer(buf, r, path)
|
||||
local mode = state and state.index_mode
|
||||
if not mode then
|
||||
mode = "100644"
|
||||
local ls = util.exec(
|
||||
{ "git", "ls-files", "-s", "--", path },
|
||||
local ls = util.git(
|
||||
{ "ls-files", "-s", "--", path },
|
||||
{ cwd = r.worktree, silent = true }
|
||||
)
|
||||
if ls then
|
||||
@@ -123,8 +123,7 @@ local function attach_index_writer(buf, r, path)
|
||||
end
|
||||
end
|
||||
if
|
||||
not util.exec({
|
||||
"git",
|
||||
not util.git({
|
||||
"update-index",
|
||||
"--cacheinfo",
|
||||
mode,
|
||||
@@ -171,8 +170,8 @@ end
|
||||
---@return boolean ok
|
||||
local function populate(buf, r, rev, state, rev_sha)
|
||||
local rev_str = rev:format()
|
||||
local stdout = util.exec(
|
||||
{ "git", "cat-file", "-p", rev_str },
|
||||
local stdout = util.git(
|
||||
{ "cat-file", "-p", rev_str },
|
||||
{ cwd = r.worktree }
|
||||
)
|
||||
if not stdout then
|
||||
|
||||
+21
-21
@@ -38,8 +38,7 @@ local global = util.Emitter.new()
|
||||
local Repo = {}
|
||||
Repo.__index = Repo
|
||||
|
||||
local STATUS_CMD = {
|
||||
"git",
|
||||
local STATUS_ARGS = {
|
||||
"--no-optional-locks",
|
||||
"-c",
|
||||
"core.quotePath=false",
|
||||
@@ -52,20 +51,22 @@ local STATUS_CMD = {
|
||||
|
||||
---@private
|
||||
function Repo:_fetch_status()
|
||||
vim.system(
|
||||
STATUS_CMD,
|
||||
{ cwd = self.worktree, text = true },
|
||||
vim.schedule_wrap(function(obj)
|
||||
util.git(STATUS_ARGS, {
|
||||
cwd = self.worktree,
|
||||
on_exit = function(result)
|
||||
self._cache = {}
|
||||
if obj.code ~= 0 then
|
||||
util.error("git status failed: %s", vim.trim(obj.stderr or ""))
|
||||
if result.code ~= 0 then
|
||||
util.error(
|
||||
"git status failed: %s",
|
||||
vim.trim(result.stderr or "")
|
||||
)
|
||||
return
|
||||
end
|
||||
self.status = status.parse(obj.stdout or "")
|
||||
self.status = status.parse(result.stdout or "")
|
||||
self._events:emit("refresh", self.status)
|
||||
global:emit("refresh", self, self.status)
|
||||
end)
|
||||
)
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
function Repo:refresh()
|
||||
@@ -242,8 +243,7 @@ end
|
||||
---@return string[]
|
||||
function Repo:list_refs()
|
||||
return self:get_cached("refs", function(self)
|
||||
local out = util.exec({
|
||||
"git",
|
||||
local out = util.git({
|
||||
"for-each-ref",
|
||||
"--format=%(refname:short)",
|
||||
"refs/heads",
|
||||
@@ -287,8 +287,8 @@ function Repo:list_stash_refs()
|
||||
return {}
|
||||
end
|
||||
local refs = { "stash" }
|
||||
local out = util.exec(
|
||||
{ "git", "stash", "list", "--pretty=format:%gd" },
|
||||
local out = util.git(
|
||||
{ "stash", "list", "--pretty=format:%gd" },
|
||||
{ cwd = self.worktree, silent = true }
|
||||
)
|
||||
if out then
|
||||
@@ -304,12 +304,12 @@ end
|
||||
---@param short boolean
|
||||
---@return string?
|
||||
function Repo:rev_parse(rev, short)
|
||||
local cmd = { "git", "rev-parse", "--verify", "--quiet" }
|
||||
local args = { "rev-parse", "--verify", "--quiet" }
|
||||
if short then
|
||||
table.insert(cmd, "--short")
|
||||
table.insert(args, "--short")
|
||||
end
|
||||
table.insert(cmd, rev)
|
||||
local stdout = util.exec(cmd, { cwd = self.worktree, silent = true })
|
||||
table.insert(args, rev)
|
||||
local stdout = util.git(args, { cwd = self.worktree, silent = true })
|
||||
local trimmed = stdout and vim.trim(stdout) or ""
|
||||
return trimmed ~= "" and trimmed or nil
|
||||
end
|
||||
@@ -321,8 +321,8 @@ end
|
||||
---@return ow.Git.Repo.ResolveStatus
|
||||
function Repo:resolve_sha(prefix)
|
||||
local result = self:get_cached("resolve:" .. prefix, function(self)
|
||||
local out = util.exec(
|
||||
{ "git", "rev-parse", "--disambiguate=" .. prefix },
|
||||
local out = util.git(
|
||||
{ "rev-parse", "--disambiguate=" .. prefix },
|
||||
{ cwd = self.worktree, silent = true }
|
||||
)
|
||||
local trimmed = out and vim.trim(out) or ""
|
||||
|
||||
+29
-29
@@ -460,18 +460,20 @@ local function action_stage()
|
||||
if #paths == 0 then
|
||||
return
|
||||
end
|
||||
local cmd = { "git", "add", "--" }
|
||||
vim.list_extend(cmd, paths)
|
||||
vim.system(
|
||||
cmd,
|
||||
{ cwd = s.repo.worktree },
|
||||
vim.schedule_wrap(function(obj)
|
||||
if obj.code ~= 0 then
|
||||
util.error("git add failed: %s", vim.trim(obj.stderr or ""))
|
||||
end
|
||||
end)
|
||||
local args = { "add", "--" }
|
||||
vim.list_extend(args, paths)
|
||||
util.git(args, {
|
||||
cwd = s.repo.worktree,
|
||||
on_exit = function(result)
|
||||
if result.code ~= 0 then
|
||||
util.error(
|
||||
"git add failed: %s",
|
||||
vim.trim(result.stderr or "")
|
||||
)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
local function action_unstage()
|
||||
local s, item = current_entry(vim.api.nvim_get_current_buf())
|
||||
@@ -481,7 +483,7 @@ local function action_unstage()
|
||||
if item.kind ~= "staged" then
|
||||
return
|
||||
end
|
||||
local cmd = { "git", "restore", "--staged", "--" }
|
||||
local args = { "restore", "--staged", "--" }
|
||||
local entries
|
||||
if item.is_header then
|
||||
entries = s.repo.status:by_kind("staged")
|
||||
@@ -494,22 +496,21 @@ local function action_unstage()
|
||||
end
|
||||
for _, e in ipairs(entries) do
|
||||
if e.orig then
|
||||
table.insert(cmd, e.orig)
|
||||
table.insert(args, e.orig)
|
||||
end
|
||||
table.insert(cmd, e.path)
|
||||
table.insert(args, e.path)
|
||||
end
|
||||
vim.system(
|
||||
cmd,
|
||||
{ cwd = s.repo.worktree },
|
||||
vim.schedule_wrap(function(obj)
|
||||
if obj.code ~= 0 then
|
||||
util.git(args, {
|
||||
cwd = s.repo.worktree,
|
||||
on_exit = function(result)
|
||||
if result.code ~= 0 then
|
||||
util.error(
|
||||
"git restore --staged failed: %s",
|
||||
vim.trim(obj.stderr or "")
|
||||
vim.trim(result.stderr or "")
|
||||
)
|
||||
end
|
||||
end)
|
||||
)
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
local function action_discard()
|
||||
@@ -542,18 +543,17 @@ local function action_discard()
|
||||
elseif item.kind == "unstaged" then
|
||||
prompt = string.format("Discard changes to %s?", item.path)
|
||||
action = function()
|
||||
vim.system(
|
||||
{ "git", "checkout", "--", item.path },
|
||||
{ cwd = s.repo.worktree },
|
||||
vim.schedule_wrap(function(obj)
|
||||
if obj.code ~= 0 then
|
||||
util.git({ "checkout", "--", item.path }, {
|
||||
cwd = s.repo.worktree,
|
||||
on_exit = function(result)
|
||||
if result.code ~= 0 then
|
||||
util.error(
|
||||
"git checkout failed: %s",
|
||||
vim.trim(obj.stderr or "")
|
||||
vim.trim(result.stderr or "")
|
||||
)
|
||||
end
|
||||
end)
|
||||
)
|
||||
end,
|
||||
})
|
||||
end
|
||||
else
|
||||
return
|
||||
|
||||
+15
-25
@@ -189,16 +189,7 @@ end
|
||||
---@field cwd string?
|
||||
---@field stdin string?
|
||||
---@field silent boolean?
|
||||
---@field on_done fun(stdout: string?)?
|
||||
|
||||
---@param args string[]
|
||||
---@param opts ow.Git.Util.ExecOpts?
|
||||
---@return string?
|
||||
function M.git(args, opts)
|
||||
local cmd = { "git" }
|
||||
vim.list_extend(cmd, args)
|
||||
return M.exec(cmd, opts)
|
||||
end
|
||||
---@field on_exit fun(result: vim.SystemCompleted)?
|
||||
|
||||
---@param cmd string[]
|
||||
---@param opts ow.Git.Util.ExecOpts?
|
||||
@@ -207,12 +198,15 @@ function M.exec(cmd, opts)
|
||||
opts = opts or {}
|
||||
local sys_opts = { cwd = opts.cwd, stdin = opts.stdin, text = true }
|
||||
|
||||
local function handle(result)
|
||||
if opts.on_exit then
|
||||
vim.system(cmd, sys_opts, vim.schedule_wrap(opts.on_exit))
|
||||
return nil
|
||||
end
|
||||
|
||||
local result = vim.system(cmd, sys_opts):wait()
|
||||
if result.code ~= 0 then
|
||||
if not opts.silent then
|
||||
local label = cmd[2] and (cmd[1] .. " " .. cmd[2])
|
||||
or cmd[1]
|
||||
or "?"
|
||||
local label = cmd[2] and (cmd[1] .. " " .. cmd[2]) or cmd[1] or "?"
|
||||
M.error("%s failed: %s", label, vim.trim(result.stderr or ""))
|
||||
end
|
||||
return nil
|
||||
@@ -220,17 +214,13 @@ function M.exec(cmd, opts)
|
||||
return result.stdout or ""
|
||||
end
|
||||
|
||||
if opts.on_done then
|
||||
vim.system(
|
||||
cmd,
|
||||
sys_opts,
|
||||
vim.schedule_wrap(function(result)
|
||||
opts.on_done(handle(result))
|
||||
end)
|
||||
)
|
||||
return nil
|
||||
end
|
||||
return handle(vim.system(cmd, sys_opts):wait())
|
||||
---@param args string[]
|
||||
---@param opts ow.Git.Util.ExecOpts?
|
||||
---@return string?
|
||||
function M.git(args, opts)
|
||||
local cmd = { "git" }
|
||||
vim.list_extend(cmd, args)
|
||||
return M.exec(cmd, opts)
|
||||
end
|
||||
|
||||
---@class ow.Git.Util.Emitter<T>
|
||||
|
||||
Reference in New Issue
Block a user