1
1
local Util = require (" lazy.util" )
2
2
local Semver = require (" lazy.manage.semver" )
3
3
local Config = require (" lazy.core.config" )
4
+ local Process = require (" lazy.manage.process" )
4
5
5
6
local M = {}
6
7
7
8
--- @alias GitInfo { branch ?: string , commit ?: string , tag ?: string , version ?: Semver }
8
9
9
- --- @param details ? boolean
10
+ --- @param repo string
11
+ --- @param details ? boolean Fetching details is slow ! Don ' t loop over a plugin to fetch all details!
10
12
--- @return GitInfo ?
11
13
function M .info (repo , details )
12
14
local line = Util .head (repo .. " /.git/HEAD" )
@@ -19,13 +21,13 @@ function M.info(repo, details)
19
21
} or { commit = line }
20
22
21
23
if details then
22
- Util . ls ( repo .. " /.git/refs/tags " , function ( _ , name )
23
- if M . ref ( repo , " tags/ " .. name ) == ret .commit then
24
- ret .tag = name
25
- ret .version = Semver .version (name )
26
- return false
24
+ for tag , tag_ref in pairs ( M . get_tag_refs ( repo )) do
25
+ if tag_ref == ret .commit then
26
+ ret .tag = tag
27
+ ret .version = Semver .version (tag )
28
+ break
27
29
end
28
- end )
30
+ end
29
31
end
30
32
return ret
31
33
end
@@ -120,7 +122,34 @@ function M.get_target(plugin)
120
122
end
121
123
122
124
function M .ref (repo , ...)
123
- return Util .head (repo .. " /.git/refs/" .. table.concat ({ ... }, " /" ))
125
+ local ref = table.concat ({ ... }, " /" )
126
+
127
+ -- if this is a tag ref, then dereference it instead
128
+ if ref :find (" tags/" , 1 , true ) == 1 then
129
+ local tags = M .get_tag_refs (repo , ref )
130
+ for _ , tag_ref in pairs (tags ) do
131
+ return tag_ref
132
+ end
133
+ end
134
+
135
+ -- otherwise just get the ref
136
+ return Util .head (repo .. " /.git/refs/" .. ref )
137
+ end
138
+
139
+ -- this is slow, so don't use on a loop over all plugins!
140
+ --- @param tagref string ?
141
+ function M .get_tag_refs (repo , tagref )
142
+ tagref = tagref or " --tags"
143
+ --- @type table<string,string>
144
+ local tags = {}
145
+ local lines = Process .exec ({ " git" , " show-ref" , " -d" , tagref }, { cwd = repo })
146
+ for _ , line in ipairs (lines ) do
147
+ local ref , tag = line :match (" ^(%w+) refs/tags/([^%^]+)%^?{?}?$" )
148
+ if ref then
149
+ tags [tag ] = ref
150
+ end
151
+ end
152
+ return tags
124
153
end
125
154
126
155
return M
0 commit comments