Skip to content

Commit

Permalink
feat(git): added support for packed-refs. Fixes #260
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed Dec 31, 2022
1 parent f656706 commit 865ff41
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 10 deletions.
52 changes: 43 additions & 9 deletions lua/lazy/manage/git.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ local M = {}
---@param details? boolean Fetching details is slow! Don't loop over a plugin to fetch all details!
---@return GitInfo?
function M.info(repo, details)
local line = Util.head(repo .. "/.git/HEAD")
local line = M.head(repo)
if line then
---@type string, string
local ref, branch = line:match("ref: (refs/heads/(.*))")
local ref, branch = line:match("ref: refs/(heads/(.*))")
local ret = ref and {
branch = branch,
commit = Util.head(repo .. "/.git/" .. ref),
commit = M.ref(repo, ref),
} or { commit = line }

if details then
Expand All @@ -33,6 +33,10 @@ function M.info(repo, details)
end
end

function M.head(repo)
return Util.head(repo .. "/.git/HEAD")
end

---@class TaggedSemver: Semver
---@field tag string

Expand All @@ -41,17 +45,32 @@ function M.get_versions(repo, spec)
local range = Semver.range(spec or "*")
---@type TaggedSemver[]
local versions = {}
Util.ls(repo .. "/.git/refs/tags", function(_, name)
local v = Semver.version(name)
for _, tag in ipairs(M.get_tags(repo)) do
local v = Semver.version(tag)
---@cast v TaggedSemver
if v and range:matches(v) then
v.tag = name
v.tag = tag
table.insert(versions, v)
end
end)
end
return versions
end

function M.get_tags(repo)
---@type string[]
local ret = {}
Util.ls(repo .. "/.git/refs/tags", function(_, name)
ret[#ret + 1] = name
end)
for name in pairs(M.packed_refs(repo)) do
local tag = name:match("^tags/(.*)")
if tag then
ret[#ret + 1] = tag
end
end
return ret
end

---@param plugin LazyPlugin
---@return string?
function M.get_branch(plugin)
Expand All @@ -69,7 +88,7 @@ function M.get_branch(plugin)
end

-- fallback to local HEAD
main = assert(Util.head(plugin.dir .. "/.git/HEAD"))
main = assert(M.head(plugin.dir))
return main and main:match("ref: refs/heads/(.*)")
end
end
Expand Down Expand Up @@ -133,7 +152,22 @@ function M.ref(repo, ...)
end

-- otherwise just get the ref
return Util.head(repo .. "/.git/refs/" .. ref)
return Util.head(repo .. "/.git/refs/" .. ref) or M.packed_refs(repo)[ref]
end

function M.packed_refs(repo)
local ok, refs = pcall(Util.read_file, repo .. "/.git/packed-refs")
---@type table<string,string>
local ret = {}
if ok then
for _, line in ipairs(vim.split(refs, "\n")) do
local ref, name = line:match("^(.*) refs/(.*)$")
if ref then
ret[name] = ref
end
end
end
return ret
end

-- this is slow, so don't use on a loop over all plugins!
Expand Down
1 change: 0 additions & 1 deletion lua/lazy/manage/task/git.lua
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ M.clone = {
self.plugin.url,
"--filter=blob:none",
"--recurse-submodules",
"--single-branch",
"--progress",
}

Expand Down

0 comments on commit 865ff41

Please sign in to comment.