From 5860ac3950252384af440847fc532367f0f91aee Mon Sep 17 00:00:00 2001 From: Damien MEHALA Date: Sun, 19 Feb 2023 16:18:24 +0100 Subject: [PATCH 1/5] Improve $GIT_DIR handling - Retrieve $GIT_DIR using `git rev-parse --absolute-git-dir` - Move $GIT_DIR ignore in the project exploration part Resolves #1976 --- lua/nvim-tree/explorer/explore.lua | 3 +- lua/nvim-tree/explorer/watch.lua | 6 +--- lua/nvim-tree/git/init.lua | 31 ++++++++++------- lua/nvim-tree/git/utils.lua | 53 ++++++++++++++++++++++++------ 4 files changed, 65 insertions(+), 28 deletions(-) diff --git a/lua/nvim-tree/explorer/explore.lua b/lua/nvim-tree/explorer/explore.lua index f3b0ea2b7b2..6f2e10d4021 100644 --- a/lua/nvim-tree/explorer/explore.lua +++ b/lua/nvim-tree/explorer/explore.lua @@ -30,7 +30,8 @@ local function populate_children(handle, cwd, node, git_status) t = get_type_from(t, abs) if - not filters.should_filter(abs, filter_status) + abs ~= git_status.git_dir + and not filters.should_filter(abs, filter_status) and not nodes_by_path[abs] and Watcher.is_fs_event_capable(abs) then diff --git a/lua/nvim-tree/explorer/watch.lua b/lua/nvim-tree/explorer/watch.lua index e80d8829176..0178fa0e8cc 100644 --- a/lua/nvim-tree/explorer/watch.lua +++ b/lua/nvim-tree/explorer/watch.lua @@ -4,10 +4,6 @@ local Watcher = require("nvim-tree.watcher").Watcher local M = {} -local function is_git(path) - return vim.fn.fnamemodify(path, ":t") == ".git" -end - local IGNORED_PATHS = { -- disable watchers on kernel filesystems -- which have a lot of unwanted events @@ -44,7 +40,7 @@ function M.create_watcher(node) path = node.absolute_path end - if is_git(path) or is_folder_ignored(path) then + if is_folder_ignored(path) then return nil end diff --git a/lua/nvim-tree/git/init.lua b/lua/nvim-tree/git/init.lua index c5be4ef02f1..9f963968ae4 100644 --- a/lua/nvim-tree/git/init.lua +++ b/lua/nvim-tree/git/init.lua @@ -143,29 +143,36 @@ function M.load_project_status(cwd) timeout = M.config.git.timeout, } + local git_directory = git_utils.get_git_directory(project_root) + local watcher = nil if M.config.filesystem_watchers.enable then log.line("watcher", "git start") - local callback = function(w) - log.line("watcher", "git event scheduled '%s'", w.project_root) - utils.debounce("git:watcher:" .. w.project_root, M.config.filesystem_watchers.debounce_delay, function() - if w.destroyed then - return - end - reload_tree_at(w.project_root) - end) - end + if git_directory == nil then + log.line("watcher", "could not found the location of .git folder") + else + local callback = function(w) + log.line("watcher", "git event scheduled '%s'", w.project_root) + utils.debounce("git:watcher:" .. w.project_root, M.config.filesystem_watchers.debounce_delay, function() + if w.destroyed then + return + end + reload_tree_at(w.project_root) + end) + end - watcher = Watcher:new(utils.path_join { project_root, ".git" }, WATCHED_FILES, callback, { - project_root = project_root, - }) + watcher = Watcher:new(git_directory, WATCHED_FILES, callback, { + project_root = project_root, + }) + end end M.projects[project_root] = { files = git_status, dirs = git_utils.file_status_to_dir_status(git_status, project_root), watcher = watcher, + git_dir = git_directory, } return M.projects[project_root] end diff --git a/lua/nvim-tree/git/utils.lua b/lua/nvim-tree/git/utils.lua index 5ec0645dd79..90c86cf398a 100644 --- a/lua/nvim-tree/git/utils.lua +++ b/lua/nvim-tree/git/utils.lua @@ -3,6 +3,22 @@ local log = require "nvim-tree.log" local has_cygpath = vim.fn.executable "cygpath" == 1 +local function norm_path(path) + -- git always returns path with forward slashes + if vim.fn.has "win32" == 1 then + -- msys2 git support + if has_cygpath then + path = vim.fn.system("cygpath -w " .. vim.fn.shellescape(path)) + if vim.v.shell_error ~= 0 then + return nil + end + end + path = path:gsub("/", "\\") + end + + return path +end + function M.get_toplevel(cwd) local profile = log.profile_start("git toplevel %s", cwd) @@ -18,16 +34,9 @@ function M.get_toplevel(cwd) return nil end - -- git always returns path with forward slashes - if vim.fn.has "win32" == 1 then - -- msys2 git support - if has_cygpath then - toplevel = vim.fn.system("cygpath -w " .. vim.fn.shellescape(toplevel)) - if vim.v.shell_error ~= 0 then - return nil - end - end - toplevel = toplevel:gsub("/", "\\") + toplevel = norm_path(toplevel) + if toplevel == nil then + return nil end -- remove newline @@ -94,4 +103,28 @@ function M.file_status_to_dir_status(status, cwd) return r end +function M.get_git_directory(cwd) + local profile = log.profile_start("git directory %s", cwd) + + local cmd = { "git", "-C", cwd, "rev-parse", "--absolute-git-dir" } + log.line("git", vim.inspect(cmd)) + + local git_dir = vim.fn.system(cmd) + + log.raw("git", git_dir) + log.profile_end(profile) + + if vim.v.shell_error ~= 0 or not git_dir or #git_dir == 0 or git_dir:match "fatal" then + return nil + end + + git_dir = norm_path(git_dir) + if git_dir == nil then + return nil + end + + -- remove newline + return git_dir:sub(0, -2) +end + return M From 1a7824694276f70428db4ab607cdfe8cf88716f3 Mon Sep 17 00:00:00 2001 From: Damien MEHALA Date: Sun, 26 Feb 2023 11:18:13 +0100 Subject: [PATCH 2/5] Code review - move norm_path to utils.lua - fix comment #2012 --- lua/nvim-tree/explorer/explore.lua | 3 +-- lua/nvim-tree/git/init.lua | 5 ++++- lua/nvim-tree/git/utils.lua | 21 ++------------------- lua/nvim-tree/utils.lua | 17 +++++++++++++++++ 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/lua/nvim-tree/explorer/explore.lua b/lua/nvim-tree/explorer/explore.lua index 6f2e10d4021..f3b0ea2b7b2 100644 --- a/lua/nvim-tree/explorer/explore.lua +++ b/lua/nvim-tree/explorer/explore.lua @@ -30,8 +30,7 @@ local function populate_children(handle, cwd, node, git_status) t = get_type_from(t, abs) if - abs ~= git_status.git_dir - and not filters.should_filter(abs, filter_status) + not filters.should_filter(abs, filter_status) and not nodes_by_path[abs] and Watcher.is_fs_event_capable(abs) then diff --git a/lua/nvim-tree/git/init.lua b/lua/nvim-tree/git/init.lua index 9f963968ae4..81bb689b513 100644 --- a/lua/nvim-tree/git/init.lua +++ b/lua/nvim-tree/git/init.lua @@ -162,6 +162,10 @@ function M.load_project_status(cwd) end) end + -- Add $GIT_DIR to the list of directory to ignore + local base_gitdir = utils.path_basename(git_directory) + table.insert(M.config.filesystem_watchers.ignore_dirs, base_gitdir) + watcher = Watcher:new(git_directory, WATCHED_FILES, callback, { project_root = project_root, }) @@ -172,7 +176,6 @@ function M.load_project_status(cwd) files = git_status, dirs = git_utils.file_status_to_dir_status(git_status, project_root), watcher = watcher, - git_dir = git_directory, } return M.projects[project_root] end diff --git a/lua/nvim-tree/git/utils.lua b/lua/nvim-tree/git/utils.lua index 90c86cf398a..658854fad04 100644 --- a/lua/nvim-tree/git/utils.lua +++ b/lua/nvim-tree/git/utils.lua @@ -1,23 +1,6 @@ local M = {} local log = require "nvim-tree.log" - -local has_cygpath = vim.fn.executable "cygpath" == 1 - -local function norm_path(path) - -- git always returns path with forward slashes - if vim.fn.has "win32" == 1 then - -- msys2 git support - if has_cygpath then - path = vim.fn.system("cygpath -w " .. vim.fn.shellescape(path)) - if vim.v.shell_error ~= 0 then - return nil - end - end - path = path:gsub("/", "\\") - end - - return path -end +local utils = require "nvim-tree.utils" function M.get_toplevel(cwd) local profile = log.profile_start("git toplevel %s", cwd) @@ -34,7 +17,7 @@ function M.get_toplevel(cwd) return nil end - toplevel = norm_path(toplevel) + toplevel = utils.norm_path(toplevel) if toplevel == nil then return nil end diff --git a/lua/nvim-tree/utils.lua b/lua/nvim-tree/utils.lua index 2604add9324..81cd91122d1 100644 --- a/lua/nvim-tree/utils.lua +++ b/lua/nvim-tree/utils.lua @@ -5,6 +5,8 @@ local M = { debouncers = {}, } +local has_cygpath = vim.fn.executable "cygpath" == 1 + M.is_unix = vim.fn.has "unix" == 1 M.is_macos = vim.fn.has "mac" == 1 or vim.fn.has "macunix" == 1 M.is_wsl = vim.fn.has "wsl" == 1 @@ -42,6 +44,21 @@ function M.path_split(path) return path:gmatch("[^" .. path_separator .. "]+" .. path_separator .. "?") end +function M.norm_path(path) + if M.is_windows then + -- msys2 git support + if has_cygpath then + path = vim.fn.system("cygpath -w " .. vim.fn.shellescape(path)) + if vim.v.shell_error ~= 0 then + return nil + end + end + path = path:gsub("/", "\\") + end + + return path +end + ---Get the basename of the given path. ---@param path string ---@return string From 844aed76a95da2fe76db4624dd39d4fb75b051a2 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 5 Mar 2023 13:11:25 +1100 Subject: [PATCH 3/5] add comments for utils.norm_path --- lua/nvim-tree/utils.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lua/nvim-tree/utils.lua b/lua/nvim-tree/utils.lua index 81cd91122d1..47ee0389136 100644 --- a/lua/nvim-tree/utils.lua +++ b/lua/nvim-tree/utils.lua @@ -10,7 +10,6 @@ local has_cygpath = vim.fn.executable "cygpath" == 1 M.is_unix = vim.fn.has "unix" == 1 M.is_macos = vim.fn.has "mac" == 1 or vim.fn.has "macunix" == 1 M.is_wsl = vim.fn.has "wsl" == 1 --- false for WSL M.is_windows = vim.fn.has "win32" == 1 or vim.fn.has "win32unix" == 1 function M.path_to_matching_str(path) @@ -44,6 +43,11 @@ function M.path_split(path) return path:gmatch("[^" .. path_separator .. "]+" .. path_separator .. "?") end +--- Normalise a path: +--- windows: replace slashes with backslashes +--- cygwin: resolve path first via cygpath +--- @param path string +--- @return string|nil nil on cygpath failure function M.norm_path(path) if M.is_windows then -- msys2 git support From d6e10e598968f19bc1e76585dc56abdeaaa857ad Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 5 Mar 2023 13:13:56 +1100 Subject: [PATCH 4/5] get_git_directory use norm_path from utils --- lua/nvim-tree/git/utils.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/nvim-tree/git/utils.lua b/lua/nvim-tree/git/utils.lua index 658854fad04..41c8634942a 100644 --- a/lua/nvim-tree/git/utils.lua +++ b/lua/nvim-tree/git/utils.lua @@ -101,7 +101,7 @@ function M.get_git_directory(cwd) return nil end - git_dir = norm_path(git_dir) + git_dir = utils.norm_path(git_dir) if git_dir == nil then return nil end From 5a83629a77778cac1c390a16b7c0ccd2b58554d2 Mon Sep 17 00:00:00 2001 From: Damien MEHALA Date: Tue, 11 Apr 2023 23:00:12 +0200 Subject: [PATCH 5/5] watcher improvements --- lua/nvim-tree/explorer/watch.lua | 14 ++++++-------- lua/nvim-tree/git/init.lua | 13 ++++++++----- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lua/nvim-tree/explorer/watch.lua b/lua/nvim-tree/explorer/watch.lua index 0178fa0e8cc..0b44bce02e3 100644 --- a/lua/nvim-tree/explorer/watch.lua +++ b/lua/nvim-tree/explorer/watch.lua @@ -4,7 +4,7 @@ local Watcher = require("nvim-tree.watcher").Watcher local M = {} -local IGNORED_PATHS = { +M.ignore_dirs = { -- disable watchers on kernel filesystems -- which have a lot of unwanted events "/sys", @@ -12,13 +12,11 @@ local IGNORED_PATHS = { "/dev", } -local function is_folder_ignored(path) - for _, folder in ipairs(IGNORED_PATHS) do - if vim.startswith(path, folder) then - return true - end - end +function M.ignore_dir(path) + table.insert(M.ignore_dirs, path) +end +local function is_folder_ignored(path) for _, ignore_dir in ipairs(M.ignore_dirs) do if vim.fn.match(path, ignore_dir) ~= -1 then return true @@ -69,7 +67,7 @@ end function M.setup(opts) M.enabled = opts.filesystem_watchers.enable M.debounce_delay = opts.filesystem_watchers.debounce_delay - M.ignore_dirs = opts.filesystem_watchers.ignore_dirs + M.ignore_dirs = vim.tbl_extend("force", M.ignore_dirs, opts.filesystem_watchers.ignore_dirs) M.uid = 0 end diff --git a/lua/nvim-tree/git/init.lua b/lua/nvim-tree/git/init.lua index 81bb689b513..7b302c45a49 100644 --- a/lua/nvim-tree/git/init.lua +++ b/lua/nvim-tree/git/init.lua @@ -2,6 +2,7 @@ local log = require "nvim-tree.log" local utils = require "nvim-tree.utils" local git_utils = require "nvim-tree.git.utils" local Runner = require "nvim-tree.git.runner" +local Watch = require "nvim-tree.explorer.watch" local Watcher = require("nvim-tree.watcher").Watcher local Iterator = require "nvim-tree.iterators.node-iterator" local explorer_node = require "nvim-tree.explorer.node" @@ -143,12 +144,13 @@ function M.load_project_status(cwd) timeout = M.config.git.timeout, } - local git_directory = git_utils.get_git_directory(project_root) - local watcher = nil + if M.config.filesystem_watchers.enable then log.line("watcher", "git start") + local git_directory = git_utils.get_git_directory(project_root) + if git_directory == nil then log.line("watcher", "could not found the location of .git folder") else @@ -162,9 +164,10 @@ function M.load_project_status(cwd) end) end - -- Add $GIT_DIR to the list of directory to ignore - local base_gitdir = utils.path_basename(git_directory) - table.insert(M.config.filesystem_watchers.ignore_dirs, base_gitdir) + -- Add GIT_DIR to the list of directory to ignore + -- local base_gitdir = utils.path_basename(git_directory) + -- Watch.ignore_dir(base_gitdir) + Watch.ignore_dir(git_directory) watcher = Watcher:new(git_directory, WATCHED_FILES, callback, { project_root = project_root,