diff --git a/lua/neogit/config.lua b/lua/neogit/config.lua index 67d79e6cd..2802d0d9c 100644 --- a/lua/neogit/config.lua +++ b/lua/neogit/config.lua @@ -330,6 +330,7 @@ end ---@field refs_view? { [string]: NeogitConfigMappingsRefsView } A dictionary that uses Refs view editor commands to set a single keybind ---@class NeogitConfig Neogit configuration settings +---@field git_binary? string The main binary to use git command with ---@field filewatcher? NeogitFilewatcherConfig Values for filewatcher ---@field graph_style? NeogitGraphStyle Style for graph ---@field commit_date_format? string Commit date format @@ -381,6 +382,7 @@ end ---@return NeogitConfig function M.get_default_values() return { + git_binary = "git", use_default_keymaps = true, disable_hint = false, disable_context_highlighting = false, diff --git a/lua/neogit/lib/git/cli.lua b/lua/neogit/lib/git/cli.lua index 315246e41..2877f9629 100644 --- a/lua/neogit/lib/git/cli.lua +++ b/lua/neogit/lib/git/cli.lua @@ -3,6 +3,7 @@ local process = require("neogit.process") local util = require("neogit.lib.util") local Path = require("plenary.path") local runner = require("neogit.runner") +local neogit = require("neogit") ---@class GitCommandSetup ---@field flags table|nil @@ -981,7 +982,7 @@ local configurations = { ---@param dir string ---@return string Absolute path of current worktree local function worktree_root(dir) - local cmd = { "git", "-C", dir, "rev-parse", "--show-toplevel" } + local cmd = { neogit.config.values.git_binary, "-C", dir, "rev-parse", "--show-toplevel" } local result = vim.system(cmd, { text = true }):wait() return Path:new(vim.trim(result.stdout)):absolute() @@ -990,7 +991,7 @@ end ---@param dir string ---@return string Absolute path of `.git/` directory local function git_dir(dir) - local cmd = { "git", "-C", dir, "rev-parse", "--git-common-dir" } + local cmd = { neogit.config.values.git_binary, "-C", dir, "rev-parse", "--git-common-dir" } local result = vim.system(cmd, { text = true }):wait() return Path:new(vim.trim(result.stdout)):absolute() @@ -999,7 +1000,7 @@ end ---@param dir string ---@return string Absolute path of `.git/` directory local function worktree_git_dir(dir) - local cmd = { "git", "-C", dir, "rev-parse", "--git-dir" } + local cmd = { neogit.config.values.git_binary, "-C", dir, "rev-parse", "--git-dir" } local result = vim.system(cmd, { text = true }):wait() return Path:new(vim.trim(result.stdout)):absolute() @@ -1008,7 +1009,7 @@ end ---@param dir string ---@return boolean local function is_inside_worktree(dir) - local cmd = { "git", "-C", dir, "rev-parse", "--is-inside-work-tree" } + local cmd = { neogit.config.values.git_binary, "-C", dir, "rev-parse", "--is-inside-work-tree" } local result = vim.system(cmd):wait() return result.code == 0 @@ -1109,7 +1110,8 @@ local mt_builder = { end, __tostring = function(tbl) return string.format( - "git %s %s %s -- %s", + "%s %s %s %s -- %s", + neogit.config.values.git_binary, tbl[k_command], table.concat(tbl[k_state].options, " "), table.concat(tbl[k_state].arguments, " "), @@ -1168,7 +1170,7 @@ local function new_builder(subcommand) -- stylua: ignore cmd = util.merge( { - "git", + neogit.config.values.git_binary, "--no-pager", "--literal-pathspecs", "--no-optional-locks", diff --git a/lua/neogit/lib/git/index.lua b/lua/neogit/lib/git/index.lua index 354eceee1..34f49e279 100644 --- a/lua/neogit/lib/git/index.lua +++ b/lua/neogit/lib/git/index.lua @@ -1,6 +1,7 @@ local git = require("neogit.lib.git") local Path = require("plenary.path") local util = require("neogit.lib.util") +local config = require("neogit.config") ---@class NeogitGitIndex local M = {} @@ -138,7 +139,7 @@ end function M.update() require("neogit.process") .new({ - cmd = { "git", "update-index", "-q", "--refresh" }, + cmd = { config.values.git_binary, "update-index", "-q", "--refresh" }, on_error = function(_) return false end, diff --git a/plugin/neogit.lua b/plugin/neogit.lua index 465eb55b8..ee929b54a 100644 --- a/plugin/neogit.lua +++ b/plugin/neogit.lua @@ -1,6 +1,8 @@ local api = vim.api api.nvim_create_user_command("Neogit", function(o) + local config = require("neogit.config") + config.values.git_binary = "git" local neogit = require("neogit") neogit.open(require("neogit.lib.util").parse_command_args(o.fargs)) end, { @@ -12,6 +14,20 @@ end, { end, }) +api.nvim_create_user_command("NeogitYadm", function(o) + local config = require("neogit.config") + config.values.git_binary = "yadm" + local neogit = require("neogit") + neogit.open(require("neogit.lib.util").parse_command_args(o.fargs)) +end, { + nargs = "*", + desc = "Open Neogit with yadm", + complete = function(arglead) + local neogit = require("neogit") + return neogit.complete(arglead) + end, +}) + api.nvim_create_user_command("NeogitResetState", function() require("neogit.lib.state")._reset() end, { nargs = "*", desc = "Reset any saved flags" }) diff --git a/tests/specs/neogit/lib/git/branch_spec.lua b/tests/specs/neogit/lib/git/branch_spec.lua index 359f38359..1b282a7ce 100644 --- a/tests/specs/neogit/lib/git/branch_spec.lua +++ b/tests/specs/neogit/lib/git/branch_spec.lua @@ -4,6 +4,7 @@ local git_harness = require("tests.util.git_harness") local neogit_util = require("neogit.lib.util") local util = require("tests.util.util") local input = require("tests.mocks.input") +local config = require("neogit.config") neogit.setup {} @@ -30,35 +31,35 @@ pending("lib.git.branch", function() end) it("returns true when feature branch has commits base branch doesn't", function() - util.system { "git", "checkout", "-b", "a-new-branch" } - util.system { "git", "reset", "--hard", "origin/master" } + util.system { config.values.git_binary, "checkout", "-b", "a-new-branch" } + util.system { config.values.git_binary, "reset", "--hard", "origin/master" } util.system { "touch", "feature.js" } - util.system { "git", "add", "." } - util.system { "git", "commit", "-m", "some feature" } + util.system { config.values.git_binary, "add", "." } + util.system { config.values.git_binary, "commit", "-m", "some feature" } assert.True(gb.is_unmerged("a-new-branch")) end) it("returns false when feature branch is fully merged into base", function() - util.system { "git", "checkout", "-b", "a-new-branch" } - util.system { "git", "reset", "--hard", "origin/master" } + util.system { config.values.git_binary, "checkout", "-b", "a-new-branch" } + util.system { config.values.git_binary, "reset", "--hard", "origin/master" } util.system { "touch", "feature.js" } - util.system { "git", "add", "." } - util.system { "git", "commit", "-m", "some feature" } - util.system { "git", "switch", "master" } - util.system { "git", "merge", "a-new-branch" } + util.system { config.values.git_binary, "add", "." } + util.system { config.values.git_binary, "commit", "-m", "some feature" } + util.system { config.values.git_binary, "switch", "master" } + util.system { config.values.git_binary, "merge", "a-new-branch" } assert.False(gb.is_unmerged("a-new-branch")) end) it("allows specifying alternate base branch", function() - util.system { "git", "checkout", "-b", "main" } - util.system { "git", "checkout", "-b", "a-new-branch" } + util.system { config.values.git_binary, "checkout", "-b", "main" } + util.system { config.values.git_binary, "checkout", "-b", "a-new-branch" } util.system { "touch", "feature.js" } - util.system { "git", "add", "." } - util.system { "git", "commit", "-m", "some feature" } - util.system { "git", "switch", "master" } - util.system { "git", "merge", "a-new-branch" } + util.system { config.values.git_binary, "add", "." } + util.system { config.values.git_binary, "commit", "-m", "some feature" } + util.system { config.values.git_binary, "switch", "master" } + util.system { config.values.git_binary, "merge", "a-new-branch" } assert.True(gb.is_unmerged("a-new-branch", "main")) assert.False(gb.is_unmerged("a-new-branch", "master")) @@ -73,12 +74,12 @@ pending("lib.git.branch", function() describe("when branch is unmerged", function() before_each(function() - util.system { "git", "checkout", "-b", "a-new-branch" } - util.system { "git", "reset", "--hard", "origin/master" } + util.system { config.values.git_binary, "checkout", "-b", "a-new-branch" } + util.system { config.values.git_binary, "reset", "--hard", "origin/master" } util.system { "touch", "feature.js" } - util.system { "git", "add", "." } - util.system { "git", "commit", "-m", "some feature" } - util.system { "git", "switch", "master" } + util.system { config.values.git_binary, "add", "." } + util.system { config.values.git_binary, "commit", "-m", "some feature" } + util.system { config.values.git_binary, "switch", "master" } end) -- These two tests seem to have a race condition where `input.confirmed` isn't set properly @@ -99,7 +100,7 @@ pending("lib.git.branch", function() describe("when branch is merged", function() it("deletes branch", function() - util.system { "git", "branch", "a-new-branch" } + util.system { config.values.git_binary, "branch", "a-new-branch" } assert.True(gb.delete("a-new-branch")) assert.False(vim.tbl_contains(gb.get_local_branches(true), "a-new-branch")) @@ -116,14 +117,14 @@ pending("lib.git.branch", function() it( "lists branches based on how recently they were checked out, excluding current & deduplicated", function() - util.system { "git", "checkout", "-b", "first" } - util.system { "git", "branch", "never-checked-out" } - util.system { "git", "checkout", "-b", "second" } - util.system { "git", "checkout", "-b", "third" } - util.system { "git", "switch", "master" } - util.system { "git", "switch", "second-branch" } - util.system { "git", "switch", "master" } - util.system { "git", "switch", "second-branch" } + util.system { config.values.git_binary, "checkout", "-b", "first" } + util.system { config.values.git_binary, "branch", "never-checked-out" } + util.system { config.values.git_binary, "checkout", "-b", "second" } + util.system { config.values.git_binary, "checkout", "-b", "third" } + util.system { config.values.git_binary, "switch", "master" } + util.system { config.values.git_binary, "switch", "second-branch" } + util.system { config.values.git_binary, "switch", "master" } + util.system { config.values.git_binary, "switch", "second-branch" } local branches_detected = gb.get_recent_local_branches() local branches = { @@ -151,7 +152,7 @@ pending("lib.git.branch", function() } for _, branch in ipairs(branches) do - vim.system({ "git", "branch", branch }):wait() + vim.system({ config.values.git_binary, "branch", branch }):wait() end table.insert(branches, "master") @@ -170,7 +171,7 @@ pending("lib.git.branch", function() end) it("properly detects all branches but the current branch", function() - vim.fn.system("git checkout master") + vim.fn.system(config.values.git_binary, " checkout master") if vim.v.shell_error ~= 0 then error("Failed to checkout master branch!") end diff --git a/tests/util/git_harness.lua b/tests/util/git_harness.lua index bcc15f294..7d4c1b64e 100644 --- a/tests/util/git_harness.lua +++ b/tests/util/git_harness.lua @@ -2,6 +2,7 @@ local neogit = require("neogit") local a = require("plenary.async") local M = {} local util = require("tests.util.util") +local config = require("neogit.config") local project_dir = util.project_dir local bare_repo_path = nil @@ -23,12 +24,12 @@ function M.setup_bare_repo() util.system { "git", "config", "user.email", "test@neogit-test.test" } util.system { "git", "config", "user.name", "Neogit Test" } - util.system { "git", "add", "." } - util.system { "git", "commit", "-m", "temp commit to be soft unstaged later" } + util.system { config.values.git_binary, "add", "." } + util.system { config.values.git_binary, "commit", "-m", "temp commit to be soft unstaged later" } bare_repo_path = util.create_temp_dir("bare-dir") - util.system { "git", "clone", "--bare", workspace_dir, bare_repo_path } + util.system { config.values.git_binary, "clone", "--bare", workspace_dir, bare_repo_path } return bare_repo_path end @@ -38,15 +39,15 @@ function M.prepare_repository() local working_dir = util.create_temp_dir("working-dir") vim.api.nvim_set_current_dir(working_dir) - util.system { "git", "clone", bare_repo_path, working_dir } - util.system { "git", "reset", "--soft", "HEAD~1" } - util.system { "git", "rm", "--cached", "untracked.txt" } - util.system { "git", "restore", "--staged", "a.txt" } - util.system { "git", "checkout", "second-branch" } - util.system { "git", "switch", "master" } - util.system { "git", "config", "remote.origin.url", "git@github.com:example/example.git" } - util.system { "git", "config", "user.email", "test@neogit-test.test" } - util.system { "git", "config", "user.name", "Neogit Test" } + util.system { config.values.git_binary, "clone", bare_repo_path, working_dir } + util.system { config.values.git_binary, "reset", "--soft", "HEAD~1" } + util.system { config.values.git_binary, "rm", "--cached", "untracked.txt" } + util.system { config.values.git_binary, "restore", "--staged", "a.txt" } + util.system { config.values.git_binary, "checkout", "second-branch" } + util.system { config.values.git_binary, "switch", "master" } + util.system { config.values.git_binary, "config", "remote.origin.url", "git@github.com:example/example.git" } + util.system { config.values.git_binary, "config", "user.email", "test@neogit-test.test" } + util.system { config.values.git_binary, "config", "user.name", "Neogit Test" } return working_dir end @@ -113,12 +114,12 @@ function M.get_current_branch() end function M.get_remotes() - local lines = exec { "git", "remote" } + local lines = exec { config.values.git_binary, "remote" } return lines end function M.get_remotes_url(remote) - local lines = exec { "git", "remote", "--get-url", remote } + local lines = exec { config.values.git_binary, "remote", "--get-url", remote } return lines[1] end diff --git a/tests/util/util.lua b/tests/util/util.lua index f9dabdcc5..61db6d788 100644 --- a/tests/util/util.lua +++ b/tests/util/util.lua @@ -1,4 +1,5 @@ local M = {} +local config = require("neogit.config") M.project_dir = vim.fn.getcwd() @@ -74,7 +75,13 @@ function M.ensure_installed(repo, path) if not vim.uv.fs_stat(install_path) then print("* Downloading " .. name .. " to '" .. install_path .. "/'") - vim.fn.system { "git", "clone", "--depth=1", "git@github.com:" .. repo .. ".git", install_path } + vim.fn.system { + config.values.git_binary, + "clone", + "--depth=1", + "git@github.com:" .. repo .. ".git", + install_path, + } if vim.v.shell_error > 0 then error(