feat(git): added support for --git-dir, --work-tree (yadm)

main
bhagwan 2 years ago
parent 1b200d3bdc
commit 604e4cf4c8

@ -432,11 +432,11 @@ end
M.git_switch = function(selected, opts) M.git_switch = function(selected, opts)
local cmd = path.git_cwd({"git", "checkout"}, opts.cwd) local cmd = path.git_cwd({"git", "checkout"}, opts)
local git_ver = utils.git_version() local git_ver = utils.git_version()
-- git switch was added with git version 2.23 -- git switch was added with git version 2.23
if git_ver and git_ver >= 2.23 then if git_ver and git_ver >= 2.23 then
cmd = path.git_cwd({"git", "switch"}, opts.cwd) cmd = path.git_cwd({"git", "switch"}, opts)
end end
-- remove anything past space -- remove anything past space
local branch = selected[1]:match("[^ ]+") local branch = selected[1]:match("[^ ]+")
@ -456,8 +456,8 @@ M.git_switch = function(selected, opts)
end end
M.git_checkout = function(selected, opts) M.git_checkout = function(selected, opts)
local cmd_checkout = path.git_cwd({"git", "checkout"}, opts.cwd) local cmd_checkout = path.git_cwd({"git", "checkout"}, opts)
local cmd_cur_commit = path.git_cwd({"git", "rev-parse", "--short HEAD"}, opts.cwd) local cmd_cur_commit = path.git_cwd({"git", "rev-parse", "--short HEAD"}, opts)
local commit_hash = selected[1]:match("[^ ]+") local commit_hash = selected[1]:match("[^ ]+")
if vim.fn.input("Checkout commit " .. commit_hash .. "? [y/n] ") == "y" then if vim.fn.input("Checkout commit " .. commit_hash .. "? [y/n] ") == "y" then
local current_commit = utils.io_systemlist(cmd_cur_commit) local current_commit = utils.io_systemlist(cmd_cur_commit)
@ -488,18 +488,18 @@ local git_exec = function(selected, opts, cmd)
end end
M.git_stage = function(selected, opts) M.git_stage = function(selected, opts)
local cmd = path.git_cwd({"git", "add", "--"}, opts.cwd) local cmd = path.git_cwd({"git", "add", "--"}, opts)
git_exec(selected, opts, cmd) git_exec(selected, opts, cmd)
end end
M.git_unstage = function(selected, opts) M.git_unstage = function(selected, opts)
local cmd = path.git_cwd({"git", "reset", "--"}, opts.cwd) local cmd = path.git_cwd({"git", "reset", "--"}, opts)
git_exec(selected, opts, cmd) git_exec(selected, opts, cmd)
end end
M.git_buf_edit = function(selected, opts) M.git_buf_edit = function(selected, opts)
local cmd = path.git_cwd({"git", "show"}, opts.cwd) local cmd = path.git_cwd({"git", "show"}, opts)
local git_root = path.git_root(opts.cwd, true) local git_root = path.git_root(opts, true)
local win = vim.api.nvim_get_current_win() local win = vim.api.nvim_get_current_win()
local buffer_filetype = vim.bo.filetype local buffer_filetype = vim.bo.filetype
local file = path.relative(vim.fn.expand("%:p"), git_root) local file = path.relative(vim.fn.expand("%:p"), git_root)

@ -761,7 +761,7 @@ function M.normalize_opts(opts, defaults)
end end
-- test for valid git_repo -- test for valid git_repo
opts.git_icons = opts.git_icons and path.is_git_repo(opts.cwd, true) opts.git_icons = opts.git_icons and path.is_git_repo(opts, true)
local executable = function(binary, fncerr, strerr) local executable = function(binary, fncerr, strerr)
if binary and vim.fn.executable(binary) ~= 1 then if binary and vim.fn.executable(binary) ~= 1 then

@ -339,6 +339,8 @@ M.mt_cmd_wrapper = function(opts)
"argv_expr", "argv_expr",
"cmd", "cmd",
"cwd", "cwd",
"git_dir",
"git_worktree",
"git_icons", "git_icons",
"file_icons", "file_icons",
"color_icons", "color_icons",

@ -192,7 +192,7 @@ M.get_diff_files = function(opts)
local diff_files = {} local diff_files = {}
local cmd = opts.git_status_cmd or config.globals.files.git_status_cmd local cmd = opts.git_status_cmd or config.globals.files.git_status_cmd
if not cmd then return {} end if not cmd then return {} end
local ok, status, err = pcall(utils.io_systemlist, path.git_cwd(cmd, opts.cwd)) local ok, status, err = pcall(utils.io_systemlist, path.git_cwd(cmd, opts))
if ok and err == 0 then if ok and err == 0 then
for i = 1, #status do for i = 1, #status do
local icon = status[i]:match("[MUDARC?]+") local icon = status[i]:match("[MUDARC?]+")

@ -228,26 +228,47 @@ function M.entry_to_file(entry, cwd, force_uri)
} }
end end
function M.git_cwd(cmd, cwd) function M.git_cwd(cmd, opts)
if not cwd then return cmd end -- backward compat, used to be single cwd param
cwd = vim.fn.expand(cwd) local o = opts or {}
if type(o) == 'string' then
o = { cwd = o }
end
local git_args = {
{ "cwd", "-C" },
{ "git_dir", "--git-dir" },
{ "git_worktree", "--work-tree" },
}
if type(cmd) == 'string' then if type(cmd) == 'string' then
local arg_cwd = ("-C %s "):format(vim.fn.shellescape(cwd)) local args = ""
cmd = cmd:gsub("^git ", "git " .. arg_cwd) for _, a in ipairs(git_args) do
if o[a[1]] then
o[a[1]] = vim.fn.expand(o[a[1]])
args = args .. ("%s %s "):format(a[2], vim.fn.shellescape(o[a[1]]))
end
end
cmd = cmd:gsub("^git ", "git " .. args)
else else
local idx = 2
cmd = utils.tbl_deep_clone(cmd) cmd = utils.tbl_deep_clone(cmd)
table.insert(cmd, 2, "-C") for _, a in ipairs(git_args) do
table.insert(cmd, 3, cwd) if o[a[1]] then
o[a[1]] = vim.fn.expand(o[a[1]])
table.insert(cmd, idx, a[2])
table.insert(cmd, idx+1, o[a[1]])
idx = idx + 2
end
end
end end
return cmd return cmd
end end
function M.is_git_repo(cwd, noerr) function M.is_git_repo(opts, noerr)
return not not M.git_root(cwd, noerr) return not not M.git_root(opts, noerr)
end end
function M.git_root(cwd, noerr) function M.git_root(opts, noerr)
local cmd = M.git_cwd({"git", "rev-parse", "--show-toplevel"}, cwd) local cmd = M.git_cwd({"git", "rev-parse", "--show-toplevel"}, opts)
local output, err = utils.io_systemlist(cmd) local output, err = utils.io_systemlist(cmd)
if err ~= 0 then if err ~= 0 then
if not noerr then utils.info(unpack(output)) end if not noerr then utils.info(unpack(output)) end

@ -239,9 +239,9 @@ Previewer.git_diff = Previewer.base:extend()
function Previewer.git_diff:new(o, opts) function Previewer.git_diff:new(o, opts)
Previewer.git_diff.super.new(self, o, opts) Previewer.git_diff.super.new(self, o, opts)
self.cmd_deleted = path.git_cwd(o.cmd_deleted, opts.cwd) self.cmd_deleted = path.git_cwd(o.cmd_deleted, opts)
self.cmd_modified = path.git_cwd(o.cmd_modified, opts.cwd) self.cmd_modified = path.git_cwd(o.cmd_modified, opts)
self.cmd_untracked = path.git_cwd(o.cmd_untracked, opts.cwd) self.cmd_untracked = path.git_cwd(o.cmd_untracked, opts)
self.pager = o.pager self.pager = o.pager
do do
-- populate the icon mappings -- populate the icon mappings

@ -8,10 +8,18 @@ local shell = require "fzf-lua.shell"
local M = {} local M = {}
local function set_git_cwd_args(opts)
opts.cwd = path.git_root(opts)
if opts.git_dir or opts.git_worktree then
opts.cmd = path.git_cwd(opts.cmd, opts)
end
return opts
end
M.files = function(opts) M.files = function(opts)
opts = config.normalize_opts(opts, config.globals.git.files) opts = config.normalize_opts(opts, config.globals.git.files)
if not opts then return end if not opts then return end
opts.cwd = path.git_root(opts.cwd) opts = set_git_cwd_args(opts)
if not opts.cwd then return end if not opts.cwd then return end
local contents = core.mt_cmd_wrapper(opts) local contents = core.mt_cmd_wrapper(opts)
opts = core.set_header(opts, 2) opts = core.set_header(opts, 2)
@ -21,10 +29,10 @@ end
M.status = function(opts) M.status = function(opts)
opts = config.normalize_opts(opts, config.globals.git.status) opts = config.normalize_opts(opts, config.globals.git.status)
if not opts then return end if not opts then return end
opts.cwd = path.git_root(opts.cwd) opts = set_git_cwd_args(opts)
if not opts.cwd then return end if not opts.cwd then return end
if opts.preview then if opts.preview then
opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts.cwd)) opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts))
end end
-- we don't need git icons since we get them -- we don't need git icons since we get them
-- as part of our `git status -s` -- as part of our `git status -s`
@ -76,7 +84,7 @@ M.status = function(opts)
end end
local function git_cmd(opts) local function git_cmd(opts)
opts.cwd = path.git_root(opts.cwd) opts = set_git_cwd_args(opts)
if not opts.cwd then return end if not opts.cwd then return end
opts = core.set_header(opts, 2) opts = core.set_header(opts, 2)
core.fzf_wrap(opts, opts.cmd, function(selected) core.fzf_wrap(opts, opts.cmd, function(selected)
@ -88,14 +96,14 @@ end
M.commits = function(opts) M.commits = function(opts)
opts = config.normalize_opts(opts, config.globals.git.commits) opts = config.normalize_opts(opts, config.globals.git.commits)
if not opts then return end if not opts then return end
opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts.cwd)) opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts))
return git_cmd(opts) return git_cmd(opts)
end end
M.bcommits = function(opts) M.bcommits = function(opts)
opts = config.normalize_opts(opts, config.globals.git.bcommits) opts = config.normalize_opts(opts, config.globals.git.bcommits)
if not opts then return end if not opts then return end
local git_root = path.git_root(opts.cwd) local git_root = path.git_root(opts)
if not git_root then return end if not git_root then return end
local file = path.relative(vim.fn.expand("%:p"), git_root) local file = path.relative(vim.fn.expand("%:p"), git_root)
opts.cmd = opts.cmd .. " " .. file opts.cmd = opts.cmd .. " " .. file
@ -104,7 +112,7 @@ M.bcommits = function(opts)
if git_ver and git_ver >= 2.31 then if git_ver and git_ver >= 2.31 then
opts.preview = opts.preview .. " --rotate-to=" .. vim.fn.shellescape(file) opts.preview = opts.preview .. " --rotate-to=" .. vim.fn.shellescape(file)
end end
opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts.cwd)) opts.preview = vim.fn.shellescape(path.git_cwd(opts.preview, opts))
return git_cmd(opts) return git_cmd(opts)
end end
@ -112,7 +120,7 @@ M.branches = function(opts)
opts = config.normalize_opts(opts, config.globals.git.branches) opts = config.normalize_opts(opts, config.globals.git.branches)
if not opts then return end if not opts then return end
opts.fzf_opts["--no-multi"] = '' opts.fzf_opts["--no-multi"] = ''
opts._preview = path.git_cwd(opts.preview, opts.cwd) opts._preview = path.git_cwd(opts.preview, opts)
opts.preview = shell.preview_action_cmd(function(items) opts.preview = shell.preview_action_cmd(function(items)
local branch = items[1]:gsub("%*", "") -- remove the * from current branch local branch = items[1]:gsub("%*", "") -- remove the * from current branch
if branch:find("%)") ~= nil then if branch:find("%)") ~= nil then

Loading…
Cancel
Save