Skip to content

Commit 865ff41

Browse files
committed
feat(git): added support for packed-refs. Fixes #260
1 parent f656706 commit 865ff41

File tree

2 files changed

+43
-10
lines changed

2 files changed

+43
-10
lines changed

lua/lazy/manage/git.lua

+43-9
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ local M = {}
1111
---@param details? boolean Fetching details is slow! Don't loop over a plugin to fetch all details!
1212
---@return GitInfo?
1313
function M.info(repo, details)
14-
local line = Util.head(repo .. "/.git/HEAD")
14+
local line = M.head(repo)
1515
if line then
1616
---@type string, string
17-
local ref, branch = line:match("ref: (refs/heads/(.*))")
17+
local ref, branch = line:match("ref: refs/(heads/(.*))")
1818
local ret = ref and {
1919
branch = branch,
20-
commit = Util.head(repo .. "/.git/" .. ref),
20+
commit = M.ref(repo, ref),
2121
} or { commit = line }
2222

2323
if details then
@@ -33,6 +33,10 @@ function M.info(repo, details)
3333
end
3434
end
3535

36+
function M.head(repo)
37+
return Util.head(repo .. "/.git/HEAD")
38+
end
39+
3640
---@class TaggedSemver: Semver
3741
---@field tag string
3842

@@ -41,17 +45,32 @@ function M.get_versions(repo, spec)
4145
local range = Semver.range(spec or "*")
4246
---@type TaggedSemver[]
4347
local versions = {}
44-
Util.ls(repo .. "/.git/refs/tags", function(_, name)
45-
local v = Semver.version(name)
48+
for _, tag in ipairs(M.get_tags(repo)) do
49+
local v = Semver.version(tag)
4650
---@cast v TaggedSemver
4751
if v and range:matches(v) then
48-
v.tag = name
52+
v.tag = tag
4953
table.insert(versions, v)
5054
end
51-
end)
55+
end
5256
return versions
5357
end
5458

59+
function M.get_tags(repo)
60+
---@type string[]
61+
local ret = {}
62+
Util.ls(repo .. "/.git/refs/tags", function(_, name)
63+
ret[#ret + 1] = name
64+
end)
65+
for name in pairs(M.packed_refs(repo)) do
66+
local tag = name:match("^tags/(.*)")
67+
if tag then
68+
ret[#ret + 1] = tag
69+
end
70+
end
71+
return ret
72+
end
73+
5574
---@param plugin LazyPlugin
5675
---@return string?
5776
function M.get_branch(plugin)
@@ -69,7 +88,7 @@ function M.get_branch(plugin)
6988
end
7089

7190
-- fallback to local HEAD
72-
main = assert(Util.head(plugin.dir .. "/.git/HEAD"))
91+
main = assert(M.head(plugin.dir))
7392
return main and main:match("ref: refs/heads/(.*)")
7493
end
7594
end
@@ -133,7 +152,22 @@ function M.ref(repo, ...)
133152
end
134153

135154
-- otherwise just get the ref
136-
return Util.head(repo .. "/.git/refs/" .. ref)
155+
return Util.head(repo .. "/.git/refs/" .. ref) or M.packed_refs(repo)[ref]
156+
end
157+
158+
function M.packed_refs(repo)
159+
local ok, refs = pcall(Util.read_file, repo .. "/.git/packed-refs")
160+
---@type table<string,string>
161+
local ret = {}
162+
if ok then
163+
for _, line in ipairs(vim.split(refs, "\n")) do
164+
local ref, name = line:match("^(.*) refs/(.*)$")
165+
if ref then
166+
ret[name] = ref
167+
end
168+
end
169+
end
170+
return ret
137171
end
138172

139173
-- this is slow, so don't use on a loop over all plugins!

lua/lazy/manage/task/git.lua

-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ M.clone = {
5858
self.plugin.url,
5959
"--filter=blob:none",
6060
"--recurse-submodules",
61-
"--single-branch",
6261
"--progress",
6362
}
6463

0 commit comments

Comments
 (0)