feat(git/repo): add Repo:head_sha for cached HEAD blob lookups

This commit is contained in:
2026-05-20 12:45:56 +02:00
parent 6230c2663c
commit 7c92b5eff6
2 changed files with 29 additions and 0 deletions
+10
View File
@@ -143,6 +143,7 @@ function Repo:_invalidate(relpath)
end end
if affects_resolve(relpath) then if affects_resolve(relpath) then
self:_clear_cache_prefix("resolve:") self:_clear_cache_prefix("resolve:")
self:_clear_cache_prefix("head_blob:")
end end
if relpath == "index" then if relpath == "index" then
self:_clear_cache_prefix("index:") self:_clear_cache_prefix("index:")
@@ -605,6 +606,15 @@ function Repo:index_sha(rel)
return sha or nil return sha or nil
end end
---@param rel string worktree-relative path
---@return string?
function Repo:head_sha(rel)
local sha = self:get_cached("head_blob:" .. rel, function(self)
return self:rev_parse("HEAD:" .. rel, false) or false
end)
return sha or nil
end
---@alias ow.Git.Repo.ResolveStatus "ok"|"ambiguous"|"missing" ---@alias ow.Git.Repo.ResolveStatus "ok"|"ambiguous"|"missing"
---@param abbrev string ---@param abbrev string
+19
View File
@@ -97,6 +97,25 @@ t.test("index_sha cache clears when the index is written", function()
wait_cleared(r, "index:a", 2000) wait_cleared(r, "index:a", 2000)
end) end)
t.test("head_sha returns the blob sha and caches it", function()
local dir = h.make_repo({ a = "x\n" })
local r = assert(require("git.core.repo").resolve(dir))
local sha = r:head_sha("a")
t.truthy(sha and #sha > 0, "head_sha returns the HEAD blob sha")
t.truthy(r._cache["head_blob:a"] ~= nil, "the result is cached")
t.eq(r:head_sha("a"), sha, "a cached call returns the same sha")
end)
t.test("head_sha cache clears when HEAD moves", function()
local dir = h.make_repo({ a = "x\n" })
local r = assert(require("git.core.repo").resolve(dir))
r:head_sha("a")
t.truthy(r._cache["head_blob:a"] ~= nil, "sha is cached before the commit")
t.write(dir, "a", "y\n")
h.git(dir, "commit", "-aqm", "change")
wait_cleared(r, "head_blob:a", 2000)
end)
t.test("cache clears after top-level .git change (commit)", function() t.test("cache clears after top-level .git change (commit)", function()
local dir = h.make_repo({ a = "x" }) local dir = h.make_repo({ a = "x" })
local r = assert(require("git.core.repo").resolve(dir)) local r = assert(require("git.core.repo").resolve(dir))