mirror of
https://github.com/lewis6991/gitsigns.nvim
synced 2024-09-16 14:34:09 +02:00
refactor: break up git.lua
This commit is contained in:
parent
aa12bb9cd2
commit
220446c8c8
5 changed files with 315 additions and 307 deletions
|
@ -29,7 +29,7 @@ local function get_gitdir_and_head()
|
|||
end
|
||||
end
|
||||
|
||||
local info = require('gitsigns.git').get_repo_info(cwd)
|
||||
local info = require('gitsigns.git').Repo.get_info(cwd)
|
||||
|
||||
return info.gitdir, info.abbrev_head
|
||||
end
|
||||
|
@ -89,7 +89,7 @@ local update_cwd_head = async.create(function()
|
|||
100,
|
||||
async.create(function()
|
||||
local git = require('gitsigns.git')
|
||||
local new_head = git.get_repo_info(cwd).abbrev_head
|
||||
local new_head = git.Repo.get_info(cwd).abbrev_head
|
||||
async.scheduler()
|
||||
vim.g.gitsigns_head = new_head
|
||||
end)
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
local async = require('gitsigns.async')
|
||||
local log = require('gitsigns.debug.log')
|
||||
local util = require('gitsigns.util')
|
||||
|
||||
local system = require('gitsigns.system').system
|
||||
local scheduler = require('gitsigns.async').scheduler
|
||||
|
||||
local uv = vim.uv or vim.loop
|
||||
local Repo = require('gitsigns.git.repo')
|
||||
|
||||
local check_version = require('gitsigns.git.version').check
|
||||
|
||||
local M = {}
|
||||
|
||||
--- @type fun(cmd: string[], opts?: vim.SystemOpts): vim.SystemCompleted
|
||||
local asystem = async.wrap(3, system)
|
||||
M.Repo = Repo
|
||||
|
||||
--- @param file string
|
||||
--- @return boolean
|
||||
|
@ -41,82 +35,7 @@ local Obj = {}
|
|||
|
||||
M.Obj = Obj
|
||||
|
||||
--- @class Gitsigns.RepoInfo
|
||||
--- @field gitdir string
|
||||
--- @field toplevel string
|
||||
--- @field detached boolean
|
||||
--- @field abbrev_head string
|
||||
|
||||
--- @class Gitsigns.Repo : Gitsigns.RepoInfo
|
||||
---
|
||||
--- Username configured for the repo.
|
||||
--- Needed for to determine "You" in current line blame.
|
||||
--- @field username string
|
||||
local Repo = {}
|
||||
M.Repo = Repo
|
||||
|
||||
--- @class Gitsigns.Git.JobSpec : vim.SystemOpts
|
||||
--- @field ignore_error? boolean
|
||||
|
||||
--- @async
|
||||
--- @param args string[]
|
||||
--- @param spec? Gitsigns.Git.JobSpec
|
||||
--- @return string[] stdout, string? stderr
|
||||
local function git_command(args, spec)
|
||||
spec = spec or {}
|
||||
|
||||
local cmd = {
|
||||
'git',
|
||||
'--no-pager',
|
||||
'--no-optional-locks',
|
||||
'--literal-pathspecs',
|
||||
'-c',
|
||||
'gc.auto=0', -- Disable auto-packing which emits messages to stderr
|
||||
unpack(args),
|
||||
}
|
||||
|
||||
if spec.text == nil then
|
||||
spec.text = true
|
||||
end
|
||||
|
||||
-- Fix #895. Only needed for Nvim 0.9 and older
|
||||
spec.clear_env = true
|
||||
|
||||
--- @type vim.SystemCompleted
|
||||
local obj = asystem(cmd, spec)
|
||||
|
||||
if not spec.ignore_error and obj.code > 0 then
|
||||
log.eprintf(
|
||||
"Received exit code %d when running command\n'%s':\n%s",
|
||||
obj.code,
|
||||
table.concat(cmd, ' '),
|
||||
obj.stderr
|
||||
)
|
||||
end
|
||||
|
||||
local stdout_lines = vim.split(obj.stdout or '', '\n')
|
||||
|
||||
if spec.text then
|
||||
-- If stdout ends with a newline, then remove the final empty string after
|
||||
-- the split
|
||||
if stdout_lines[#stdout_lines] == '' then
|
||||
stdout_lines[#stdout_lines] = nil
|
||||
end
|
||||
end
|
||||
|
||||
if log.verbose then
|
||||
log.vprintf('%d lines:', #stdout_lines)
|
||||
for i = 1, math.min(10, #stdout_lines) do
|
||||
log.vprintf('\t%s', stdout_lines[i])
|
||||
end
|
||||
end
|
||||
|
||||
if obj.stderr == '' then
|
||||
obj.stderr = nil
|
||||
end
|
||||
|
||||
return stdout_lines, obj.stderr
|
||||
end
|
||||
local git_command = require('gitsigns.git.cmd')
|
||||
|
||||
--- @async
|
||||
--- @param file_cmp string
|
||||
|
@ -142,194 +61,6 @@ function M.diff(file_cmp, file_buf, indent_heuristic, diff_algo)
|
|||
})
|
||||
end
|
||||
|
||||
--- @async
|
||||
--- @param gitdir? string
|
||||
--- @param head_str string
|
||||
--- @param cwd string
|
||||
--- @return string
|
||||
local function process_abbrev_head(gitdir, head_str, cwd)
|
||||
if not gitdir then
|
||||
return head_str
|
||||
end
|
||||
if head_str == 'HEAD' then
|
||||
local short_sha = git_command({ 'rev-parse', '--short', 'HEAD' }, {
|
||||
ignore_error = true,
|
||||
cwd = cwd,
|
||||
})[1] or ''
|
||||
if log.debug_mode and short_sha ~= '' then
|
||||
short_sha = 'HEAD'
|
||||
end
|
||||
if
|
||||
util.path_exists(gitdir .. '/rebase-merge')
|
||||
or util.path_exists(gitdir .. '/rebase-apply')
|
||||
then
|
||||
return short_sha .. '(rebasing)'
|
||||
end
|
||||
return short_sha
|
||||
end
|
||||
return head_str
|
||||
end
|
||||
|
||||
local has_cygpath = jit and jit.os == 'Windows' and vim.fn.executable('cygpath') == 1
|
||||
|
||||
--- @param path? string
|
||||
--- @return string?
|
||||
local function normalize_path(path)
|
||||
if path and has_cygpath and not uv.fs_stat(path) then
|
||||
-- If on windows and path isn't recognizable as a file, try passing it
|
||||
-- through cygpath
|
||||
path = asystem({ 'cygpath', '-aw', path }).stdout
|
||||
end
|
||||
return path
|
||||
end
|
||||
|
||||
--- @async
|
||||
--- @param cwd string
|
||||
--- @param gitdir? string
|
||||
--- @param toplevel? string
|
||||
--- @return Gitsigns.RepoInfo
|
||||
function M.get_repo_info(cwd, gitdir, toplevel)
|
||||
-- Does git rev-parse have --absolute-git-dir, added in 2.13:
|
||||
-- https://public-inbox.org/git/20170203024829.8071-16-szeder.dev@gmail.com/
|
||||
local has_abs_gd = check_version({ 2, 13 })
|
||||
|
||||
-- Wait for internal scheduler to settle before running command (#215)
|
||||
scheduler()
|
||||
|
||||
local args = {}
|
||||
|
||||
if gitdir then
|
||||
vim.list_extend(args, { '--git-dir', gitdir })
|
||||
end
|
||||
|
||||
if toplevel then
|
||||
vim.list_extend(args, { '--work-tree', toplevel })
|
||||
end
|
||||
|
||||
vim.list_extend(args, {
|
||||
'rev-parse',
|
||||
'--show-toplevel',
|
||||
has_abs_gd and '--absolute-git-dir' or '--git-dir',
|
||||
'--abbrev-ref',
|
||||
'HEAD',
|
||||
})
|
||||
|
||||
local results = git_command(args, {
|
||||
ignore_error = true,
|
||||
cwd = toplevel or cwd,
|
||||
})
|
||||
|
||||
local toplevel_r = normalize_path(results[1])
|
||||
local gitdir_r = normalize_path(results[2])
|
||||
|
||||
if gitdir_r and not has_abs_gd then
|
||||
gitdir_r = assert(uv.fs_realpath(gitdir_r))
|
||||
end
|
||||
|
||||
return {
|
||||
toplevel = toplevel_r,
|
||||
gitdir = gitdir_r,
|
||||
abbrev_head = process_abbrev_head(gitdir_r, results[3], cwd),
|
||||
detached = toplevel_r and gitdir_r ~= toplevel_r .. '/.git',
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Git repo object methods
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
--- Run git command the with the objects gitdir and toplevel
|
||||
--- @async
|
||||
--- @param args string[]
|
||||
--- @param spec? Gitsigns.Git.JobSpec
|
||||
--- @return string[] stdout, string? stderr
|
||||
function Repo:command(args, spec)
|
||||
spec = spec or {}
|
||||
spec.cwd = self.toplevel
|
||||
|
||||
local args1 = { '--git-dir', self.gitdir }
|
||||
|
||||
if self.detached then
|
||||
vim.list_extend(args1, { '--work-tree', self.toplevel })
|
||||
end
|
||||
|
||||
vim.list_extend(args1, args)
|
||||
|
||||
return git_command(args1, spec)
|
||||
end
|
||||
|
||||
--- @return string[]
|
||||
function Repo:files_changed()
|
||||
--- @type string[]
|
||||
local results = self:command({ 'status', '--porcelain', '--ignore-submodules' })
|
||||
|
||||
local ret = {} --- @type string[]
|
||||
for _, line in ipairs(results) do
|
||||
if line:sub(1, 2):match('^.M') then
|
||||
ret[#ret + 1] = line:sub(4, -1)
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
--- @param encoding string
|
||||
--- @return boolean
|
||||
local function iconv_supported(encoding)
|
||||
-- TODO(lewis6991): needs https://github.com/neovim/neovim/pull/21924
|
||||
if vim.startswith(encoding, 'utf-16') then
|
||||
return false
|
||||
elseif vim.startswith(encoding, 'utf-32') then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--- Get version of file in the index, return array lines
|
||||
--- @param object string
|
||||
--- @param encoding? string
|
||||
--- @return string[] stdout, string? stderr
|
||||
function Repo:get_show_text(object, encoding)
|
||||
local stdout, stderr = self:command({ 'show', object }, { text = false, ignore_error = true })
|
||||
|
||||
if encoding and encoding ~= 'utf-8' and iconv_supported(encoding) then
|
||||
for i, l in ipairs(stdout) do
|
||||
stdout[i] = vim.iconv(l, encoding, 'utf-8')
|
||||
end
|
||||
end
|
||||
|
||||
return stdout, stderr
|
||||
end
|
||||
|
||||
--- @async
|
||||
function Repo:update_abbrev_head()
|
||||
self.abbrev_head = M.get_repo_info(self.toplevel).abbrev_head
|
||||
end
|
||||
|
||||
--- @async
|
||||
--- @param dir string
|
||||
--- @param gitdir? string
|
||||
--- @param toplevel? string
|
||||
--- @return Gitsigns.Repo
|
||||
function Repo.new(dir, gitdir, toplevel)
|
||||
local self = setmetatable({}, { __index = Repo })
|
||||
|
||||
local info = M.get_repo_info(dir, gitdir, toplevel)
|
||||
for k, v in
|
||||
pairs(info --[[@as table<string,any>]])
|
||||
do
|
||||
---@diagnostic disable-next-line:no-unknown
|
||||
self[k] = v
|
||||
end
|
||||
|
||||
self.username = self:command({ 'config', 'user.name' }, { ignore_error = true })[1]
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Git object methods
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
--- @param revision? string
|
||||
function Obj:update_revision(revision)
|
||||
self.revision = util.norm_base(revision)
|
||||
|
@ -525,35 +256,6 @@ function Obj:unstage_file()
|
|||
autocmd_changed(self.file)
|
||||
end
|
||||
|
||||
--- @class Gitsigns.CommitInfo
|
||||
--- @field author string
|
||||
--- @field author_mail string
|
||||
--- @field author_time integer
|
||||
--- @field author_tz string
|
||||
--- @field committer string
|
||||
--- @field committer_mail string
|
||||
--- @field committer_time integer
|
||||
--- @field committer_tz string
|
||||
--- @field summary string
|
||||
--- @field sha string
|
||||
--- @field abbrev_sha string
|
||||
--- @field boundary? true
|
||||
|
||||
--- @class Gitsigns.BlameInfoPublic: Gitsigns.BlameInfo, Gitsigns.CommitInfo
|
||||
--- @field body? string[]
|
||||
--- @field hunk_no? integer
|
||||
--- @field num_hunks? integer
|
||||
--- @field hunk? string[]
|
||||
--- @field hunk_head? string
|
||||
|
||||
--- @class Gitsigns.BlameInfo
|
||||
--- @field orig_lnum integer
|
||||
--- @field final_lnum integer
|
||||
--- @field commit Gitsigns.CommitInfo
|
||||
--- @field filename string
|
||||
--- @field previous_filename? string
|
||||
--- @field previous_sha? string
|
||||
|
||||
--- @param lines string[]
|
||||
--- @param lnum? integer
|
||||
--- @param revision? string
|
||||
|
@ -585,15 +287,13 @@ end
|
|||
--- Stage 'lines' as the entire contents of the file
|
||||
--- @param lines string[]
|
||||
function Obj:stage_lines(lines)
|
||||
local stdout = self.repo:command({
|
||||
local new_object = self.repo:command({
|
||||
'hash-object',
|
||||
'-w',
|
||||
'--path',
|
||||
self.relpath,
|
||||
'--stdin',
|
||||
}, { stdin = lines })
|
||||
|
||||
local new_object = stdout[1]
|
||||
}, { stdin = lines })[1]
|
||||
|
||||
self.repo:command({
|
||||
'update-index',
|
||||
|
|
|
@ -3,6 +3,35 @@ local uv = vim.uv or vim.loop
|
|||
local error_once = require('gitsigns.message').error_once
|
||||
local dprintf = require('gitsigns.debug.log').dprintf
|
||||
|
||||
--- @class Gitsigns.CommitInfo
|
||||
--- @field author string
|
||||
--- @field author_mail string
|
||||
--- @field author_time integer
|
||||
--- @field author_tz string
|
||||
--- @field committer string
|
||||
--- @field committer_mail string
|
||||
--- @field committer_time integer
|
||||
--- @field committer_tz string
|
||||
--- @field summary string
|
||||
--- @field sha string
|
||||
--- @field abbrev_sha string
|
||||
--- @field boundary? true
|
||||
|
||||
--- @class Gitsigns.BlameInfoPublic: Gitsigns.BlameInfo, Gitsigns.CommitInfo
|
||||
--- @field body? string[]
|
||||
--- @field hunk_no? integer
|
||||
--- @field num_hunks? integer
|
||||
--- @field hunk? string[]
|
||||
--- @field hunk_head? string
|
||||
|
||||
--- @class Gitsigns.BlameInfo
|
||||
--- @field orig_lnum integer
|
||||
--- @field final_lnum integer
|
||||
--- @field commit Gitsigns.CommitInfo
|
||||
--- @field filename string
|
||||
--- @field previous_filename? string
|
||||
--- @field previous_sha? string
|
||||
|
||||
local NOT_COMMITTED = {
|
||||
author = 'Not Committed Yet',
|
||||
author_mail = '<not.committed.yet>',
|
||||
|
|
72
lua/gitsigns/git/cmd.lua
Normal file
72
lua/gitsigns/git/cmd.lua
Normal file
|
@ -0,0 +1,72 @@
|
|||
local async = require('gitsigns.async')
|
||||
local log = require('gitsigns.debug.log')
|
||||
|
||||
local system = require('gitsigns.system').system
|
||||
|
||||
--- @type fun(cmd: string[], opts?: vim.SystemOpts): vim.SystemCompleted
|
||||
local asystem = async.wrap(3, system)
|
||||
|
||||
--- @class Gitsigns.Git.JobSpec : vim.SystemOpts
|
||||
--- @field ignore_error? boolean
|
||||
|
||||
--- @async
|
||||
--- @param args string[]
|
||||
--- @param spec? Gitsigns.Git.JobSpec
|
||||
--- @return string[] stdout, string? stderr
|
||||
local function git_command(args, spec)
|
||||
spec = spec or {}
|
||||
|
||||
local cmd = {
|
||||
'git',
|
||||
'--no-pager',
|
||||
'--no-optional-locks',
|
||||
'--literal-pathspecs',
|
||||
'-c',
|
||||
'gc.auto=0', -- Disable auto-packing which emits messages to stderr
|
||||
unpack(args),
|
||||
}
|
||||
|
||||
if spec.text == nil then
|
||||
spec.text = true
|
||||
end
|
||||
|
||||
-- Fix #895. Only needed for Nvim 0.9 and older
|
||||
spec.clear_env = true
|
||||
|
||||
--- @type vim.SystemCompleted
|
||||
local obj = asystem(cmd, spec)
|
||||
|
||||
if not spec.ignore_error and obj.code > 0 then
|
||||
log.eprintf(
|
||||
"Received exit code %d when running command\n'%s':\n%s",
|
||||
obj.code,
|
||||
table.concat(cmd, ' '),
|
||||
obj.stderr
|
||||
)
|
||||
end
|
||||
|
||||
local stdout_lines = vim.split(obj.stdout or '', '\n')
|
||||
|
||||
if spec.text then
|
||||
-- If stdout ends with a newline, then remove the final empty string after
|
||||
-- the split
|
||||
if stdout_lines[#stdout_lines] == '' then
|
||||
stdout_lines[#stdout_lines] = nil
|
||||
end
|
||||
end
|
||||
|
||||
if log.verbose then
|
||||
log.vprintf('%d lines:', #stdout_lines)
|
||||
for i = 1, math.min(10, #stdout_lines) do
|
||||
log.vprintf('\t%s', stdout_lines[i])
|
||||
end
|
||||
end
|
||||
|
||||
if obj.stderr == '' then
|
||||
obj.stderr = nil
|
||||
end
|
||||
|
||||
return stdout_lines, obj.stderr
|
||||
end
|
||||
|
||||
return git_command
|
207
lua/gitsigns/git/repo.lua
Normal file
207
lua/gitsigns/git/repo.lua
Normal file
|
@ -0,0 +1,207 @@
|
|||
local async = require('gitsigns.async')
|
||||
local git_command = require('gitsigns.git.cmd')
|
||||
local log = require('gitsigns.debug.log')
|
||||
local util = require('gitsigns.util')
|
||||
|
||||
local system = require('gitsigns.system').system
|
||||
local check_version = require('gitsigns.git.version').check
|
||||
|
||||
--- @type fun(cmd: string[], opts?: vim.SystemOpts): vim.SystemCompleted
|
||||
local asystem = async.wrap(3, system)
|
||||
|
||||
local uv = vim.uv or vim.loop
|
||||
|
||||
--- @class Gitsigns.RepoInfo
|
||||
--- @field gitdir string
|
||||
--- @field toplevel string
|
||||
--- @field detached boolean
|
||||
--- @field abbrev_head string
|
||||
|
||||
--- @class Gitsigns.Repo : Gitsigns.RepoInfo
|
||||
---
|
||||
--- Username configured for the repo.
|
||||
--- Needed for to determine "You" in current line blame.
|
||||
--- @field username string
|
||||
local M = {}
|
||||
|
||||
--- Run git command the with the objects gitdir and toplevel
|
||||
--- @async
|
||||
--- @param args string[]
|
||||
--- @param spec? Gitsigns.Git.JobSpec
|
||||
--- @return string[] stdout, string? stderr
|
||||
function M:command(args, spec)
|
||||
spec = spec or {}
|
||||
spec.cwd = self.toplevel
|
||||
|
||||
local args1 = { '--git-dir', self.gitdir }
|
||||
|
||||
if self.detached then
|
||||
vim.list_extend(args1, { '--work-tree', self.toplevel })
|
||||
end
|
||||
|
||||
vim.list_extend(args1, args)
|
||||
|
||||
return git_command(args1, spec)
|
||||
end
|
||||
|
||||
--- @return string[]
|
||||
function M:files_changed()
|
||||
--- @type string[]
|
||||
local results = self:command({ 'status', '--porcelain', '--ignore-submodules' })
|
||||
|
||||
local ret = {} --- @type string[]
|
||||
for _, line in ipairs(results) do
|
||||
if line:sub(1, 2):match('^.M') then
|
||||
ret[#ret + 1] = line:sub(4, -1)
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
--- @param encoding string
|
||||
--- @return boolean
|
||||
local function iconv_supported(encoding)
|
||||
-- TODO(lewis6991): needs https://github.com/neovim/neovim/pull/21924
|
||||
if vim.startswith(encoding, 'utf-16') then
|
||||
return false
|
||||
elseif vim.startswith(encoding, 'utf-32') then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--- Get version of file in the index, return array lines
|
||||
--- @param object string
|
||||
--- @param encoding? string
|
||||
--- @return string[] stdout, string? stderr
|
||||
function M:get_show_text(object, encoding)
|
||||
local stdout, stderr = self:command({ 'show', object }, { text = false, ignore_error = true })
|
||||
|
||||
if encoding and encoding ~= 'utf-8' and iconv_supported(encoding) then
|
||||
for i, l in ipairs(stdout) do
|
||||
stdout[i] = vim.iconv(l, encoding, 'utf-8')
|
||||
end
|
||||
end
|
||||
|
||||
return stdout, stderr
|
||||
end
|
||||
|
||||
--- @async
|
||||
function M:update_abbrev_head()
|
||||
self.abbrev_head = M.get_info(self.toplevel).abbrev_head
|
||||
end
|
||||
|
||||
--- @async
|
||||
--- @param dir string
|
||||
--- @param gitdir? string
|
||||
--- @param toplevel? string
|
||||
--- @return Gitsigns.Repo
|
||||
function M.new(dir, gitdir, toplevel)
|
||||
local self = setmetatable({}, { __index = M })
|
||||
|
||||
local info = M.get_info(dir, gitdir, toplevel)
|
||||
for k, v in
|
||||
pairs(info --[[@as table<string,any>]])
|
||||
do
|
||||
---@diagnostic disable-next-line:no-unknown
|
||||
self[k] = v
|
||||
end
|
||||
|
||||
self.username = self:command({ 'config', 'user.name' }, { ignore_error = true })[1]
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
local has_cygpath = jit and jit.os == 'Windows' and vim.fn.executable('cygpath') == 1
|
||||
|
||||
--- @param path? string
|
||||
--- @return string?
|
||||
local function normalize_path(path)
|
||||
if path and has_cygpath and not uv.fs_stat(path) then
|
||||
-- If on windows and path isn't recognizable as a file, try passing it
|
||||
-- through cygpath
|
||||
path = asystem({ 'cygpath', '-aw', path }).stdout
|
||||
end
|
||||
return path
|
||||
end
|
||||
|
||||
--- @async
|
||||
--- @param gitdir? string
|
||||
--- @param head_str string
|
||||
--- @param cwd string
|
||||
--- @return string
|
||||
local function process_abbrev_head(gitdir, head_str, cwd)
|
||||
if not gitdir then
|
||||
return head_str
|
||||
end
|
||||
if head_str == 'HEAD' then
|
||||
local short_sha = git_command({ 'rev-parse', '--short', 'HEAD' }, {
|
||||
ignore_error = true,
|
||||
cwd = cwd,
|
||||
})[1] or ''
|
||||
if log.debug_mode and short_sha ~= '' then
|
||||
short_sha = 'HEAD'
|
||||
end
|
||||
if
|
||||
util.path_exists(gitdir .. '/rebase-merge')
|
||||
or util.path_exists(gitdir .. '/rebase-apply')
|
||||
then
|
||||
return short_sha .. '(rebasing)'
|
||||
end
|
||||
return short_sha
|
||||
end
|
||||
return head_str
|
||||
end
|
||||
|
||||
--- @async
|
||||
--- @param cwd string
|
||||
--- @param gitdir? string
|
||||
--- @param toplevel? string
|
||||
--- @return Gitsigns.RepoInfo
|
||||
function M.get_info(cwd, gitdir, toplevel)
|
||||
-- Does git rev-parse have --absolute-git-dir, added in 2.13:
|
||||
-- https://public-inbox.org/git/20170203024829.8071-16-szeder.dev@gmail.com/
|
||||
local has_abs_gd = check_version({ 2, 13 })
|
||||
|
||||
-- Wait for internal scheduler to settle before running command (#215)
|
||||
async.scheduler()
|
||||
|
||||
local args = {}
|
||||
|
||||
if gitdir then
|
||||
vim.list_extend(args, { '--git-dir', gitdir })
|
||||
end
|
||||
|
||||
if toplevel then
|
||||
vim.list_extend(args, { '--work-tree', toplevel })
|
||||
end
|
||||
|
||||
vim.list_extend(args, {
|
||||
'rev-parse',
|
||||
'--show-toplevel',
|
||||
has_abs_gd and '--absolute-git-dir' or '--git-dir',
|
||||
'--abbrev-ref',
|
||||
'HEAD',
|
||||
})
|
||||
|
||||
local results = git_command(args, {
|
||||
ignore_error = true,
|
||||
cwd = toplevel or cwd,
|
||||
})
|
||||
|
||||
local toplevel_r = normalize_path(results[1])
|
||||
local gitdir_r = normalize_path(results[2])
|
||||
|
||||
if gitdir_r and not has_abs_gd then
|
||||
gitdir_r = assert(uv.fs_realpath(gitdir_r))
|
||||
end
|
||||
|
||||
return {
|
||||
toplevel = toplevel_r,
|
||||
gitdir = gitdir_r,
|
||||
abbrev_head = process_abbrev_head(gitdir_r, results[3], cwd),
|
||||
detached = toplevel_r and gitdir_r ~= toplevel_r .. '/.git',
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
Loading…
Reference in a new issue