From 9950f48f7e8f8042652c93ac8287f712d333b0bd Mon Sep 17 00:00:00 2001 From: Alfonso Ros Date: Wed, 14 Dec 2022 19:44:57 +0100 Subject: [PATCH] fix: use fugitive functions to parse fugitive:// url Fixes #686 --- lua/gitsigns.lua | 23 +++++++++-------------- lua/gitsigns/git.lua | 11 ++++++++--- lua/gitsigns/test.lua | 8 -------- teal/gitsigns.tl | 25 ++++++++++--------------- teal/gitsigns/git.tl | 11 ++++++++--- teal/gitsigns/test.tl | 8 -------- types/vim.d.tl | 9 +++++++++ types/vim/fn.d.tl | 3 +++ 8 files changed, 47 insertions(+), 51 deletions(-) diff --git a/lua/gitsigns.lua b/lua/gitsigns.lua index 227fb5e0..27e6a177 100644 --- a/lua/gitsigns.lua +++ b/lua/gitsigns.lua @@ -36,9 +36,6 @@ local M = {} - - - function M.detach_all() for k, _ in pairs(cache) do M.detach(k) @@ -73,18 +70,20 @@ function M.detach(bufnr, _keep_signs) cache:destroy(bufnr) end + local function parse_fugitive_uri(name) - local _, _, root_path, sub_module_path, commit, real_path = - name:find([[^fugitive://(.*)/%.git(.*/)/(%x-)/(.*)]]) + if vim.g.loaded_fugitive == 0 then + dprint("Fugitive not installed") + return + end + + local path = vim.fn.FugitiveReal(name) + local commit = vim.fn.FugitiveParse(name)[1]:match('([^:]+):.*') if commit == '0' then commit = nil end - if root_path then - sub_module_path = sub_module_path:gsub("^/modules", "") - name = root_path .. sub_module_path .. real_path - end - return name, commit + return path, commit end local function parse_gitsigns_uri(name) @@ -460,10 +459,6 @@ M.setup = void(function(cfg) autocmd('DirChanged', debounce_trailing(100, manager.update_cwd_head)) end) -if _TEST then - M.parse_fugitive_uri = parse_fugitive_uri -end - return setmetatable(M, { __index = function(_, f) return (require('gitsigns.actions'))[f] diff --git a/lua/gitsigns/git.lua b/lua/gitsigns/git.lua index 4acc4948..7650a902 100644 --- a/lua/gitsigns/git.lua +++ b/lua/gitsigns/git.lua @@ -170,8 +170,12 @@ end local git_command = async.create(function(args, spec) spec = spec or {} spec.command = spec.command or 'git' - spec.args = spec.command == 'git' and - { '--no-pager', '--literal-pathspecs', unpack(args) } or args + spec.args = spec.command == 'git' and { + '--no-pager', + '--literal-pathspecs', + '-c', 'gc.auto=0', + unpack(args), + } or args if not spec.cwd and not uv.cwd() then spec.cwd = vim.env.HOME @@ -181,7 +185,8 @@ local git_command = async.create(function(args, spec) if not spec.suppress_stderr then if stderr then - gsd.eprint(stderr) + local cmd_str = table.concat({ spec.command, unpack(args) }, ' ') + gsd.eprintf("Recieved stderr when running command\n'%s':\n%s", cmd_str, stderr) end end diff --git a/lua/gitsigns/test.lua b/lua/gitsigns/test.lua index cbed9d95..9c3958c3 100644 --- a/lua/gitsigns/test.lua +++ b/lua/gitsigns/test.lua @@ -32,12 +32,4 @@ M._tests.test_args = function() eq(pos_args[1], 'posarg') end -M._tests.test_name_parse = function() - local gs = require('gitsigns') - local path, commit = gs.parse_fugitive_uri( - 'fugitive:///home/path/to/project/.git//1b441b947c4bc9a59db428f229456619051dd133/subfolder/to/a/file.txt') - eq(path, '/home/path/to/project/subfolder/to/a/file.txt') - eq(commit, '1b441b947c4bc9a59db428f229456619051dd133') -end - return M diff --git a/teal/gitsigns.tl b/teal/gitsigns.tl index fc542b98..48b96c64 100644 --- a/teal/gitsigns.tl +++ b/teal/gitsigns.tl @@ -33,9 +33,6 @@ local record M detach : function(bufnr: integer, _keep_signs: boolean) detach_all : function() attach : function(cbuf: integer, trigger: string) - - -- Exposed for tests - parse_fugitive_uri: function(name: string): string, string end --- Detach Gitsigns from all buffers it is attached to. @@ -73,18 +70,20 @@ function M.detach(bufnr: integer, _keep_signs: boolean) cache:destroy(bufnr) end +-- @return (string, string) Tuple of buffer name and commit local function parse_fugitive_uri(name: string): string, string - local _, _, root_path, sub_module_path, commit, real_path = - name:find([[^fugitive://(.*)/%.git(.*/)/(%x-)/(.*)]]) + if vim.g.loaded_fugitive == 0 then + dprint("Fugitive not installed") + return + end + + local path = vim.fn.FugitiveReal(name) + local commit = vim.fn.FugitiveParse(name)[1]:match('([^:]+):.*') if commit == '0' then - -- '0' means the index so cleat commit so we attach normally + -- '0' means the index so clear commit so we attach normally commit = nil end - if root_path then - sub_module_path = sub_module_path:gsub("^/modules", "") - name = root_path .. sub_module_path .. real_path - end - return name, commit + return path, commit end local function parse_gitsigns_uri(name: string): string, string @@ -460,10 +459,6 @@ M.setup = void(function(cfg: Config) autocmd('DirChanged', debounce_trailing(100, manager.update_cwd_head)) end) -if _TEST then - M.parse_fugitive_uri = parse_fugitive_uri -end - return setmetatable(M, { __index = function(_, f: string): any return (require('gitsigns.actions') as {string:function})[f] diff --git a/teal/gitsigns/git.tl b/teal/gitsigns/git.tl index 2fc83ede..fc32b3e4 100644 --- a/teal/gitsigns/git.tl +++ b/teal/gitsigns/git.tl @@ -170,8 +170,12 @@ end local git_command = async.create(function(args: {string}, spec: GJobSpec): {string}, string spec = spec or {} spec.command = spec.command or 'git' - spec.args = spec.command == 'git' and - { '--no-pager', '--literal-pathspecs', unpack(args) } or args + spec.args = spec.command == 'git' and { + '--no-pager', + '--literal-pathspecs', + '-c', 'gc.auto=0', -- Disable auto-packing which emits messages to stderr + unpack(args) + } or args if not spec.cwd and not uv.cwd() then spec.cwd = vim.env.HOME @@ -181,7 +185,8 @@ local git_command = async.create(function(args: {string}, spec: GJobSpec): {stri if not spec.suppress_stderr then if stderr then - gsd.eprint(stderr) + local cmd_str = table.concat({spec.command, unpack(args)}, ' ') + gsd.eprintf("Recieved stderr when running command\n'%s':\n%s", cmd_str, stderr) end end diff --git a/teal/gitsigns/test.tl b/teal/gitsigns/test.tl index be1d3745..c7f529db 100644 --- a/teal/gitsigns/test.tl +++ b/teal/gitsigns/test.tl @@ -32,12 +32,4 @@ M._tests.test_args = function() eq(pos_args[1], 'posarg') end -M._tests.test_name_parse = function() - local gs = require'gitsigns' - local path, commit = gs.parse_fugitive_uri( - 'fugitive:///home/path/to/project/.git//1b441b947c4bc9a59db428f229456619051dd133/subfolder/to/a/file.txt') - eq(path, '/home/path/to/project/subfolder/to/a/file.txt') - eq(commit, '1b441b947c4bc9a59db428f229456619051dd133') -end - return M diff --git a/types/vim.d.tl b/types/vim.d.tl index 92e149e1..58e074ec 100644 --- a/types/vim.d.tl +++ b/types/vim.d.tl @@ -91,6 +91,7 @@ local record M record g gitsigns_head: string + loaded_fugitive: integer end record v @@ -148,6 +149,14 @@ local record M pesc: function(string): string + record Regex + userdata + + match_str: function(Regex, string): integer, integer + end + + regex: function(string): Regex + startswith: function(string, string): boolean endswith: function(string, string): boolean diff --git a/types/vim/fn.d.tl b/types/vim/fn.d.tl index acbedc7f..7b709d36 100644 --- a/types/vim/fn.d.tl +++ b/types/vim/fn.d.tl @@ -74,6 +74,9 @@ local record M systemlist: function({string}): {string} tempname: function(): string type: function(any): integer + + FugitiveReal: function(...: any): string + FugitiveParse: function(...: any): {string, string} end return M