fix(git): dereference tag refs. Fixes #54

This commit is contained in:
Folke Lemaitre 2022-12-21 10:13:18 +01:00
parent e95da35d09
commit 86eaa118c6
No known key found for this signature in database
GPG Key ID: 41F8B1FBACAE2040
1 changed files with 37 additions and 8 deletions

View File

@ -1,12 +1,14 @@
local Util = require("lazy.util") local Util = require("lazy.util")
local Semver = require("lazy.manage.semver") local Semver = require("lazy.manage.semver")
local Config = require("lazy.core.config") local Config = require("lazy.core.config")
local Process = require("lazy.manage.process")
local M = {} local M = {}
---@alias GitInfo {branch?:string, commit?:string, tag?:string, version?:Semver} ---@alias GitInfo {branch?:string, commit?:string, tag?:string, version?:Semver}
---@param details? boolean ---@param repo string
---@param details? boolean Fetching details is slow! Don't loop over a plugin to fetch all details!
---@return GitInfo? ---@return GitInfo?
function M.info(repo, details) function M.info(repo, details)
local line = Util.head(repo .. "/.git/HEAD") local line = Util.head(repo .. "/.git/HEAD")
@ -19,13 +21,13 @@ function M.info(repo, details)
} or { commit = line } } or { commit = line }
if details then if details then
Util.ls(repo .. "/.git/refs/tags", function(_, name) for tag, tag_ref in pairs(M.get_tag_refs(repo)) do
if M.ref(repo, "tags/" .. name) == ret.commit then if tag_ref == ret.commit then
ret.tag = name ret.tag = tag
ret.version = Semver.version(name) ret.version = Semver.version(tag)
return false break
end end
end) end
end end
return ret return ret
end end
@ -120,7 +122,34 @@ function M.get_target(plugin)
end end
function M.ref(repo, ...) function M.ref(repo, ...)
return Util.head(repo .. "/.git/refs/" .. table.concat({ ... }, "/")) local ref = table.concat({ ... }, "/")
-- if this is a tag ref, then dereference it instead
if ref:find("tags/", 1, true) == 1 then
local tags = M.get_tag_refs(repo, ref)
for _, tag_ref in pairs(tags) do
return tag_ref
end
end
-- otherwise just get the ref
return Util.head(repo .. "/.git/refs/" .. ref)
end
-- this is slow, so don't use on a loop over all plugins!
---@param tagref string?
function M.get_tag_refs(repo, tagref)
tagref = tagref or "--tags"
---@type table<string,string>
local tags = {}
local lines = Process.exec({ "git", "show-ref", "-d", tagref }, { cwd = repo })
for _, line in ipairs(lines) do
local ref, tag = line:match("^(%w+) refs/tags/([^%^]+)%^?{?}?$")
if ref then
tags[tag] = ref
end
end
return tags
end end
return M return M