refactor(git): introduce Revision class, normalize naming, slim docs

This commit is contained in:
2026-04-30 09:44:24 +02:00
parent 775add9b15
commit d95de4bc1d
10 changed files with 244 additions and 428 deletions
+7 -25
View File
@@ -12,7 +12,7 @@ M.UNMERGED = {
UU = true,
}
---@param code string porcelain v1 XY code
---@param code string
---@return string? char
---@return string? hl_group
function M.indicator(code)
@@ -84,10 +84,6 @@ function M.resolve(path)
return vim.fs.normalize(gitdir), worktree
end
---Resolve the gitdir/worktree from the current buffer's file path,
---falling back to `vim.fn.getcwd()` when the buffer is unnamed or
---carries a synthetic URI (`git://`, `gitlog://`) that isn't a real
---filesystem path. Returns nil for both when not inside a git repo.
---@return string? gitdir
---@return string? worktree
function M.resolve_cwd()
@@ -101,7 +97,7 @@ end
---@class ow.Git.Repo
---@field gitdir string
---@field worktree string
---@field buffers table<integer, true> set of registered buffer numbers
---@field buffers table<integer, true>
---@field watcher? uv.uv_fs_event_t
---@field refresh fun(self: ow.Git.Repo)
---@field refresh_handle ow.Git.Util.DebounceHandle
@@ -121,9 +117,8 @@ end
function Repo:stop_watcher()
-- Stop the libuv watcher first so no further fs-events can trigger
-- self:refresh(). Only then tear down the debounce handle. The reverse
-- order leaves a window where an in-flight watcher callback would call
-- a closed debounce timer.
-- self:refresh(). Tearing down the debounce handle first leaves a
-- window where an in-flight watcher callback hits a closed timer.
if self.watcher then
self.watcher:stop()
self.watcher:close()
@@ -149,11 +144,6 @@ end
---@param repo ow.Git.Repo
local function do_refresh(repo)
-- `--branch` adds the `## branch...upstream [ahead/behind]` line that
-- the sidebar parses. The per-buffer indicator only needs the XY +
-- path lines, so it ignores `##` lines below. Running with `--branch`
-- lets the sidebar reuse this single subprocess via the GitRefresh
-- data payload instead of spawning its own.
vim.system(
{
"git",
@@ -173,10 +163,6 @@ local function do_refresh(repo)
local x = code:sub(1, 1)
local y = code:sub(2, 2)
local path_part = line:sub(4)
-- ` -> ` only appears in renames/copies. Without
-- this guard, a literal filename containing the
-- arrow (rare with `core.quotePath=false`) would
-- be mis-parsed.
if x == "R" or x == "C" or y == "R" or y == "C" then
local arrow = path_part:find(" -> ", 1, true)
if arrow then
@@ -325,20 +311,16 @@ function M.head(path)
return nil
end
---Resolve a git revision to its object SHA. Returns nil if the ref can't
---be parsed (root-commit's `^`, blob's `^`, malformed ref, etc.). When
---`short` is true, the result is abbreviated via `core.abbrev`
---(auto-extended by git to keep the prefix unique in the current repo).
---@param worktree string
---@param ref string
---@param rev string
---@param short boolean
---@return string?
function M.rev_parse(worktree, ref, short)
function M.rev_parse(worktree, rev, short)
local cmd = { "git", "rev-parse", "--verify", "--quiet" }
if short then
table.insert(cmd, "--short")
end
table.insert(cmd, ref)
table.insert(cmd, rev)
local stdout = util.exec(cmd, { cwd = worktree, silent = true })
local trimmed = stdout and vim.trim(stdout) or ""
return trimmed ~= "" and trimmed or nil