feat(git): replace vim-fugitive with custom git module
This commit is contained in:
+7
-108
@@ -1,3 +1,4 @@
|
||||
local diff = require("git.diff")
|
||||
local log = require("log")
|
||||
local repo = require("git.repo")
|
||||
|
||||
@@ -361,109 +362,6 @@ local function current_entry(bufnr)
|
||||
return s, s.lines[lnum]
|
||||
end
|
||||
|
||||
---@param buf integer
|
||||
---@param worktree string
|
||||
---@param path string
|
||||
local function attach_index_writer(buf, worktree, path)
|
||||
vim.api.nvim_create_autocmd("BufWriteCmd", {
|
||||
buffer = buf,
|
||||
callback = function()
|
||||
local body = table.concat(
|
||||
vim.api.nvim_buf_get_lines(buf, 0, -1, false),
|
||||
"\n"
|
||||
) .. "\n"
|
||||
local hash = vim.system(
|
||||
{ "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 "")
|
||||
return
|
||||
end
|
||||
local sha = vim.trim(hash.stdout or "")
|
||||
local mode = "100644"
|
||||
local ls = vim.system(
|
||||
{ "git", "ls-files", "-s", "--", path },
|
||||
{ cwd = worktree, text = true }
|
||||
):wait()
|
||||
if ls.code == 0 and ls.stdout then
|
||||
local m = ls.stdout:match("^(%d+)")
|
||||
if m then
|
||||
mode = m
|
||||
end
|
||||
end
|
||||
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 "")
|
||||
return
|
||||
end
|
||||
vim.bo[buf].modified = false
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
---@param worktree string
|
||||
---@param ref string '' for index, 'HEAD' for HEAD
|
||||
---@param path string
|
||||
---@param is_index boolean? true to hook :w to update the git index
|
||||
---@return integer
|
||||
local function git_show_buf(worktree, ref, path, is_index)
|
||||
local result = vim.system(
|
||||
{ "git", "show", ref .. ":" .. path },
|
||||
{ cwd = worktree, text = true }
|
||||
):wait()
|
||||
local content = result.code == 0 and (result.stdout or "") or ""
|
||||
local lines = vim.split(content, "\n", { plain = true, trimempty = false })
|
||||
if #lines > 0 and lines[#lines] == "" then
|
||||
table.remove(lines)
|
||||
end
|
||||
local buf = vim.api.nvim_create_buf(false, true)
|
||||
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
|
||||
vim.bo[buf].buftype = is_index and "acwrite" or "nofile"
|
||||
vim.bo[buf].bufhidden = "wipe"
|
||||
vim.bo[buf].swapfile = false
|
||||
if not is_index then
|
||||
vim.bo[buf].modifiable = false
|
||||
end
|
||||
if is_index then
|
||||
attach_index_writer(buf, worktree, path)
|
||||
end
|
||||
vim.bo[buf].modified = false
|
||||
return buf
|
||||
end
|
||||
|
||||
---@return integer
|
||||
local function empty_buf()
|
||||
local buf = vim.api.nvim_create_buf(false, true)
|
||||
vim.bo[buf].buftype = "nofile"
|
||||
vim.bo[buf].bufhidden = "wipe"
|
||||
vim.bo[buf].swapfile = false
|
||||
vim.bo[buf].modifiable = false
|
||||
vim.bo[buf].modified = false
|
||||
return buf
|
||||
end
|
||||
|
||||
---@param abs_path string
|
||||
---@return integer
|
||||
local function load_file_buf(abs_path)
|
||||
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
|
||||
if
|
||||
vim.api.nvim_buf_is_loaded(buf)
|
||||
and vim.api.nvim_buf_get_name(buf) == abs_path
|
||||
then
|
||||
return buf
|
||||
end
|
||||
end
|
||||
local buf = vim.fn.bufadd(abs_path)
|
||||
vim.fn.bufload(buf)
|
||||
return buf
|
||||
end
|
||||
|
||||
---@class ow.Git.DiffSide
|
||||
---@field buf integer
|
||||
---@field name string?
|
||||
@@ -478,7 +376,8 @@ end
|
||||
---@return ow.Git.DiffSide
|
||||
local function head_pane(worktree, path, content)
|
||||
return {
|
||||
buf = content and git_show_buf(worktree, "HEAD", path) or empty_buf(),
|
||||
buf = content and diff.git_show_buf(worktree, "HEAD", path)
|
||||
or diff.empty_buf(),
|
||||
name = "git://HEAD/" .. path,
|
||||
}
|
||||
end
|
||||
@@ -490,11 +389,11 @@ end
|
||||
local function worktree_pane(worktree, path, exists)
|
||||
if exists then
|
||||
return {
|
||||
buf = load_file_buf(vim.fs.joinpath(worktree, path)),
|
||||
buf = diff.load_file_buf(vim.fs.joinpath(worktree, path)),
|
||||
name = nil,
|
||||
}
|
||||
end
|
||||
return { buf = empty_buf(), name = "git://worktree/" .. path }
|
||||
return { buf = diff.empty_buf(), name = "git://worktree/" .. path }
|
||||
end
|
||||
|
||||
---@param s ow.Git.StatusState
|
||||
@@ -506,8 +405,8 @@ local function index_pane(s, entry)
|
||||
or (entry.section == "Staged" and entry.x == "D")
|
||||
)
|
||||
return {
|
||||
buf = in_index and git_show_buf(s.worktree, "", entry.path, true)
|
||||
or empty_buf(),
|
||||
buf = in_index and diff.git_show_buf(s.worktree, "", entry.path, true)
|
||||
or diff.empty_buf(),
|
||||
name = "git://index/" .. entry.path,
|
||||
}
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user