diff --git a/lua/git/core/repo.lua b/lua/git/core/repo.lua index d9a75ac..e29b805 100644 --- a/lua/git/core/repo.lua +++ b/lua/git/core/repo.lua @@ -108,6 +108,9 @@ local INVALIDATION_RULES = { stash_refs = function(relpath) return relpath == "refs/stash" or relpath == "logs/refs/stash" end, + config = function(relpath) + return relpath == "config" + end, } ---@param relpath string @@ -599,6 +602,37 @@ function Repo:resolve_sha(abbrev) return result[1], result[2] end +---@private +---@return table> +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 local no_repo_dirs = {} diff --git a/lua/git/statusline.lua b/lua/git/statusline.lua index 99fb2c7..33592e7 100644 --- a/lua/git/statusline.lua +++ b/lua/git/statusline.lua @@ -38,7 +38,7 @@ end ---@param r ow.Git.Repo ---@param rel string 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_string = render(entry) end diff --git a/test/git/repo_test.lua b/test/git/repo_test.lua index 366436d..a66e689 100644 --- a/test/git/repo_test.lua +++ b/test/git/repo_test.lua @@ -173,6 +173,34 @@ t.test("_invalidate clears refs/head/resolve for refs/heads/*", function() t.truthy(r._cache.stash_refs) 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() local dir = h.make_repo({ a = "x" }) local r = assert(require("git.core.repo").resolve(dir))