Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Application slow closing directories with .git contained #2997

Open
djames-bloom opened this issue Nov 9, 2024 · 12 comments
Open

Application slow closing directories with .git contained #2997

djames-bloom opened this issue Nov 9, 2024 · 12 comments
Labels
awaiting feedback bug Something isn't working

Comments

@djames-bloom
Copy link

djames-bloom commented Nov 9, 2024

Description

After upgrading to 0.10.*, closing nvim causes a long pause, up to 10 seconds.

This seems to be similar to #2438, but it is replicable with zero changes made to the cleanroom config, and is not related to node_modules or any similar large directory.

This is replicable using the absolute barebones cleanroom config without any changes made.

There appears to be no relevant info in nvim-tree.log as all logged lines occurs before the attempted close.


This behaviour has two interesting cases

  1. If any subdirectories of the open path contains a .git directory, the bug occurs, it does not only apply to the root open path
  2. The issue also persists if a .git directory simply exists without being an actual git repo

Neovim version

NVIM v0.10.2
Build type: Release
LuaJIT 2.1.1727870382
git version 2.47.0

Operating system and version

MacOS 14.1

Windows variant

No response

nvim-tree version

c763948

Clean room replication

vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1

vim.cmd([[set runtimepath=$VIMRUNTIME]])
vim.cmd([[set packpath=/tmp/nvt-min/site]])
local package_root = "/tmp/nvt-min/site/pack"
local install_path = package_root .. "/packer/start/packer.nvim"
local function load_plugins()
  require("packer").startup({
    {
      "wbthomason/packer.nvim",
      "nvim-tree/nvim-tree.lua",
      "nvim-tree/nvim-web-devicons",
      -- ADD PLUGINS THAT ARE _NECESSARY_ FOR REPRODUCING THE ISSUE
    },
    config = {
      package_root = package_root,
      compile_path = install_path .. "/plugin/packer_compiled.lua",
      display = { non_interactive = true },
    },
  })
end
if vim.fn.isdirectory(install_path) == 0 then
  print("Installing nvim-tree and dependencies.")
  vim.fn.system({ "git", "clone", "--depth=1", "https://github.com/wbthomason/packer.nvim", install_path })
end
load_plugins()
require("packer").sync()
vim.cmd([[autocmd User PackerComplete ++once echo "Ready!" | lua setup()]])
vim.opt.termguicolors = true
vim.opt.cursorline = true

-- MODIFY NVIM-TREE SETTINGS THAT ARE _NECESSARY_ FOR REPRODUCING THE ISSUE
_G.setup = function()
  require("nvim-tree").setup({
	log = {
		enable = true,
		truncate = true,
		types = {
			all = false,
			config = false,
			copy_paste = false,
			dev = false,
			diagnostics = true,
			git = true,
			profile = true,
			watcher = true,
		},
	},
  })
end

-- UNCOMMENT this block for diagnostics issues, substituting pattern and cmd as appropriate.
-- Requires diagnostics.enable = true in setup.
--[[
vim.api.nvim_create_autocmd("FileType", {
  pattern = "lua",
  callback = function()
    vim.lsp.start {
      name = "my-luals",
      cmd = { "lua-language-server" },
      root_dir = vim.loop.cwd(),
    }
  end,
})
]]

Steps to reproduce

  1. Create a new directory to test in
  2. Initialize a git repo in the directory, or create an empty .git directory within
  3. Open directory with cleanroom configuration
  4. Toggle the visibility of the tree
  5. Close the project

Expected behavior

Standard close behavior.

Actual behavior

A hang/delay of up to 10 seconds before nvim closes.

@djames-bloom djames-bloom added the bug Something isn't working label Nov 9, 2024
@djames-bloom djames-bloom changed the title Application slow closing directories git repos Application slow closing directories with .git contained Nov 9, 2024
@djames-bloom
Copy link
Author

As mentioned, this issue happens when a sub-directory contains .git paths

e.g. the following structure triggers the issue

.
├── dummy.go
├── main.go
└── subdir
    └── .git

3 directories, 2 files

@alex-courtis
Copy link
Member

alex-courtis commented Nov 9, 2024

Sorry, not able to replicate this one on linux. Attempt:

: ; find /tmp/treedebug -ls
     1588      0 drwxr-xr-x   3 alex     users         100 Nov 10 09:18 /tmp/treedebug
     1589      0 -rw-r--r--   1 alex     users           0 Nov 10 09:18 /tmp/treedebug/dummy.go
     1590      0 -rw-r--r--   1 alex     users           0 Nov 10 09:18 /tmp/treedebug/main.go
     1603      0 drwxr-xr-x   3 alex     users          60 Nov 10 09:18 /tmp/treedebug/subdir
     1604      0 drwxr-xr-x   2 alex     users          40 Nov 10 09:18 /tmp/treedebug/subdir/.git

Collected a log, normalised and compared to yours:

: ; uudiff 2997.log actual.log
--- 2997.log	2024-11-10 09:23:53.799669092 +1100
+++ actual.log	2024-11-10 09:33:13.543302474 +1100
@@ -1,32 +1,36 @@
 [profile] START core init /tmp/treedebug
 [watcher] Watcher:create '/tmp/treedebug' nil
 [watcher] Event:create '/tmp/treedebug'
 [watcher] Event:start '/tmp/treedebug'
 [profile] START git toplevel git_dir /tmp/treedebug
 [git] git -C /tmp/treedebug rev-parse --show-toplevel --absolute-git-dir
-fatal: not a git repository (or any of the parent directories): .git
+fatal: not a git repository (or any parent up to mount point /)
+Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
 [profile] END   git toplevel git_dir /tmp/treedebug ms
 [profile] START explore /tmp/treedebug
 [profile] START populate_children /tmp/treedebug/dummy.go
 [profile] END   populate_children /tmp/treedebug/dummy.go ms
 [profile] START populate_children /tmp/treedebug/main.go
 [profile] END   populate_children /tmp/treedebug/main.go ms
 [profile] START populate_children /tmp/treedebug/subdir
 [watcher] Watcher:create '/tmp/treedebug/subdir' nil
 [watcher] Event:create '/tmp/treedebug/subdir'
 [watcher] Event:start '/tmp/treedebug/subdir'
 [profile] END   populate_children /tmp/treedebug/subdir ms
 [profile] END   explore /tmp/treedebug ms
 [profile] END   core init /tmp/treedebug ms
+[profile] START view open
+[profile] END   view open ms
 [profile] START draw
 [profile] END   draw ms
-[profile] START reload /tmp/treedebug
-[profile] END   reload /tmp/treedebug ms
 [profile] START git toplevel git_dir /tmp/treedebug/subdir
 [git] git -C /tmp/treedebug/subdir rev-parse --show-toplevel --absolute-git-dir
-fatal: not a git repository (or any of the parent directories): .git
+fatal: not a git repository (or any parent up to mount point /)
+Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
 [profile] END   git toplevel git_dir /tmp/treedebug/subdir ms
-[profile] START reload /tmp/treedebug/subdir
-[profile] END   reload /tmp/treedebug/subdir ms
+[profile] START explore /tmp/treedebug/subdir
+[profile] START populate_children /tmp/treedebug/subdir/.git
+[profile] END   populate_children /tmp/treedebug/subdir/.git ms
+[profile] END   explore /tmp/treedebug/subdir ms
 [profile] START draw
 [profile] END   draw ms

That +Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set). might be interesting, or may just be a difference between git implementations. Have you got anything interesting or unusual in your ~/.gitconfig?

I'd be grateful if you can perform some further tests:

  • repeat in a regular directory under your home - not /tmp
  • filesystem_watchers.enable = false
  • git.enable = false
  • try the previous minor versions 1.7.0 1.6.0 ...

@alex-courtis
Copy link
Member

Rolling back to minor versions:

cd /path/to/nvim-tree.lua
git pull
git checkout v1.7.0

When you're finished testing:

git checkout master

@djames-bloom
Copy link
Author

djames-bloom commented Nov 11, 2024

Hey Alex, thanks for looking into this

RE gitconfig, it doesn't look like theres anything in there that would be causing this kind of effect, but in case, you can find a copy here.

I'll update this comment once I've had a chance to run the additional tests.


Edit: testing the above results in the following, in a path in my home directory, using the cleanroom config

  • filesystem_watchers.enable = false - Appears to resolve - log
  • git.enable = false - No change - log

Disabling the above changes and testing with previous versions

  • v1.7.0 - slow
  • v1.6.0 - slow
  • v1.5.0 - slow
  • v1.4.0 - slow

@alex-courtis
Copy link
Member

alex-courtis commented Nov 16, 2024

filesystem_watchers.enable = false - Appears to resolve - log

git toplevel takes 25ms, for me (linux) it's 5ms, however that's not a great issue. You might want to try git fsmonitor daemon

git.enable = false - No change - log

Matches my times.

It seem that the issue is the filesystem watchers, specifically closing them. Are you running any virus scanners or similar file system monitoring daemons?

@alex-courtis
Copy link
Member

This might be a vim problem. Please try this:

mkdir "${HOME}/fs_event_test"
cd "${HOME}/fs_event_test"
touch {1000..9999}
nvim
:source /tmp/foo.lua

Creation should be near-instant.
Time exiting, also should be instant.

/tmp/foo.lua:

local fail

local FS_EVENT_FLAGS = {
  stat = false,
  recursive = false,
}

local function create_fs_event(path)
  -- print("create_fs_event: " .. path)

  local fs_event
  fs_event, _, fail = vim.loop.new_fs_event()

  if not fs_event then
    print(path .. " " .. fail)
    os.exit(1)
  end

  local rc
  rc, _, fail = fs_event:start(path, FS_EVENT_FLAGS, function()
    print("callback " .. path)
  end)

  if rc ~= 0 then
    print(path .. " " .. fail)
    os.exit(2)
  end
end

for i = 1000, 9999, 1 do
  create_fs_event(tostring(i))
end

print("created all events successfully")

@michaelvanstraten
Copy link

I can confirm this issue on the following setup:

  • System:
    Darwin Kernel Version 23.6.0: Fri Jul  5 17:55:37 PDT 2024; root:xnu-10063.141.1~2/RELEASE_ARM64_T6030
    
  • Neovim version:
    NVIM v0.10.2
    Build type: Release
    LuaJIT 2.1.1713773202
    
    (Run with nvim -V1 -v for more details)

To reproduce the issue, I needed to open a few directories and a file.

Here is a performance profile captured while browsing the mozilla-central repository.

@alex-courtis
Copy link
Member

Thanks for the additional info; I'm not quite sure what to do with it or how to read the profile output.

Did you perform this test? #2997 (comment)

We need to isolate whether this is an nvim-tree issue or a neovim issue, by attempting to replicate without nvim-tree.

To reproduce the issue, I needed to open a few directories and a file.

What exactly needs to be done? How would I replicate this?

I'll need full instructions on the profiler and how to read it.

@michaelvanstraten
Copy link

@alex-courtis sorry for the confusion. I will hopefully have the time to add some instructions later.

I will run the test in #2997 (comment) as soon as I am home from work.

michaelvanstraten added a commit to michaelvanstraten/systems that referenced this issue Dec 10, 2024
@TrevorHinesley
Copy link

FWIW @michaelvanstraten's change here fixes this for me, though that's obviously a nuclear option.

@michaelvanstraten
Copy link

@TrevorHinesley i did the same, thank you.

@alex-courtis
Copy link
Member

I also do that for one massive repo that I work on when using macos: https://github.com/alex-courtis/arch/blob/497777f10727f7f4ff4f85a903168054f878e051/config/nvim/lua/amc/plugins/nvt.lua#L217

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting feedback bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants