feat(git): case-insensitive status lookup on ignorecase repos
This commit is contained in:
@@ -108,6 +108,9 @@ local INVALIDATION_RULES = {
|
|||||||
stash_refs = function(relpath)
|
stash_refs = function(relpath)
|
||||||
return relpath == "refs/stash" or relpath == "logs/refs/stash"
|
return relpath == "refs/stash" or relpath == "logs/refs/stash"
|
||||||
end,
|
end,
|
||||||
|
config = function(relpath)
|
||||||
|
return relpath == "config"
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
---@param relpath string
|
---@param relpath string
|
||||||
@@ -599,6 +602,37 @@ function Repo:resolve_sha(abbrev)
|
|||||||
return result[1], result[2]
|
return result[1], result[2]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@private
|
||||||
|
---@return table<string, table<string, string>>
|
||||||
|
function Repo:_config()
|
||||||
|
return self:get_cached("config", function(self)
|
||||||
|
return read_git_config(vim.fs.joinpath(self.gitdir, "config")) or {}
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@private
|
||||||
|
---@return boolean
|
||||||
|
function Repo:_ignorecase()
|
||||||
|
local cfg = self:_config()
|
||||||
|
return cfg.core and cfg.core.ignorecase == "true" or false
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param rel string
|
||||||
|
---@return ow.Git.Status.Entry?
|
||||||
|
function Repo:status_entry_for(rel)
|
||||||
|
local direct = self.status.entries[rel]
|
||||||
|
if direct or not self:_ignorecase() then
|
||||||
|
return direct
|
||||||
|
end
|
||||||
|
local lower = rel:lower()
|
||||||
|
for path, entry in pairs(self.status.entries) do
|
||||||
|
if path:lower() == lower then
|
||||||
|
return entry
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
---@type table<string, true>
|
---@type table<string, true>
|
||||||
local no_repo_dirs = {}
|
local no_repo_dirs = {}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ end
|
|||||||
---@param r ow.Git.Repo
|
---@param r ow.Git.Repo
|
||||||
---@param rel string
|
---@param rel string
|
||||||
local function set_status(buf, r, rel)
|
local function set_status(buf, r, rel)
|
||||||
local entry = r.status.entries[rel]
|
local entry = r:status_entry_for(rel)
|
||||||
vim.b[buf].git_status = { head = r:head(), entry = entry }
|
vim.b[buf].git_status = { head = r:head(), entry = entry }
|
||||||
vim.b[buf].git_status_string = render(entry)
|
vim.b[buf].git_status_string = render(entry)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -173,6 +173,34 @@ t.test("_invalidate clears refs/head/resolve for refs/heads/*", function()
|
|||||||
t.truthy(r._cache.stash_refs)
|
t.truthy(r._cache.stash_refs)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
t.test("_invalidate clears config on .git/config change", function()
|
||||||
|
local dir = h.make_repo({ a = "x" })
|
||||||
|
local r = assert(require("git.core.repo").resolve(dir))
|
||||||
|
r._cache.config = { core = {} }
|
||||||
|
r:_invalidate("config")
|
||||||
|
t.eq(r._cache.config, nil)
|
||||||
|
end)
|
||||||
|
|
||||||
|
t.test("status_entry_for: exact match on case-sensitive repo", function()
|
||||||
|
local dir = h.make_repo({ Foo = "x" })
|
||||||
|
t.write(dir, "Foo", "modified")
|
||||||
|
local r = assert(require("git.core.repo").resolve(dir))
|
||||||
|
wait_initial(r)
|
||||||
|
t.truthy(r:status_entry_for("Foo"))
|
||||||
|
t.eq(r:status_entry_for("foo"), nil, "case mismatch returns nil")
|
||||||
|
end)
|
||||||
|
|
||||||
|
t.test("status_entry_for: case-insensitive fallback when core.ignorecase=true", function()
|
||||||
|
local dir = h.make_repo({ Foo = "x" })
|
||||||
|
h.git(dir, "config", "core.ignorecase", "true")
|
||||||
|
t.write(dir, "Foo", "modified")
|
||||||
|
local r = assert(require("git.core.repo").resolve(dir))
|
||||||
|
wait_initial(r)
|
||||||
|
t.truthy(r:status_entry_for("Foo"), "exact match")
|
||||||
|
t.truthy(r:status_entry_for("foo"), "lowercase finds Foo")
|
||||||
|
t.truthy(r:status_entry_for("FOO"), "uppercase finds Foo")
|
||||||
|
end)
|
||||||
|
|
||||||
t.test("_invalidate matches stash_refs on refs/stash and logs/refs/stash", function()
|
t.test("_invalidate matches stash_refs on refs/stash and logs/refs/stash", 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))
|
||||||
|
|||||||
Reference in New Issue
Block a user