jesseduffield / jesseduffield/lazygit

Disable core.fsmonitor for read-only background/polling git commands

Open
#5,851 2 comments 1 reaction 0 assignees View on GitHub
Dominant language
Go
Stars
82.4k
Forks
3k
Avg merge
2d 18h
Merged PRs (30d)
19

Description

### Is your feature request related to a problem? Please describe.
Lazygit already disables git's optional locks globally (`GIT_OPTIONAL_LOCKS=0`, see `pkg/commands/git_cmd_obj_builder.go`), which is great. However, on repos with `core.fsmonitor=true`, lazygit's background refresh commands (`status`, `diff --numstat`, etc.) still query the persistent `git fsmonitor--daemon` on every refresh cycle — optional-locks and fsmonitor-querying are independent mechanisms, so disabling one doesn't disable the other.

Each fsmonitor query makes the daemon create and then delete a "cookie" file under `.git/worktrees//fsmonitor--daemon/cookies/` as part of its internal handshake protocol. Other tools watching the same `.git` directory for external changes pick up that filesystem churn (confirmed via `fswatch`/`eslogger` tracing) and trigger their own full git-status re-polls, even though nothing in the repo actually changed. Filed as zed-industries/zed#61561 against Zed specifically, but the root trigger is lazygit's own polling commands not opting out of fsmonitor for read-only background queries.

### Describe the solution you'd like
Add `-c core.fsmonitor=false` to lazygit's read-only/background polling git commands — the ones run on the refresh timer rather than in direct response to a user action. This avoids pinging the fsmonitor daemon (and the resulting cookie-file churn) for queries that don't need fsmonitor's speed benefit as much as an interactive foreground command might.

### Describe alternatives you've considered
Leaving it as-is — no correctness issue for lazygit itself. But it has real side effects on other tools sharing the repo (Zed, and potentially any other file-watcher-driven git integration) and on EDR/security agents that hook process exec/exit and produce log noise from racing lazygit's short-lived subprocess bursts.

Unlike optional-locks, this isn't a completely free change: `core.fsmonitor` exists to make status/diff faster on large repos by avoiding a full working-tree scan, so disabling it for background polling trades a bit of background-refresh speed on very large repos for eliminating the side-effect churn. Happy to discuss whether that tradeoff is worth it, or whether it should be configurable.

### Additional context
Root-caused via `eslogger exec` (parent-PID tracing) and `fswatch` on `.git/worktrees//fsmonitor--daemon/cookies/`, showing the cookie churn firing in lockstep with lazygit's refresh interval, and stopping entirely when lazygit quits.

Contributor guide

Open the contributing guide

Research direction

Start with pkg/commands/git_cmd_obj_builder.go, then trace the background refresh commands named in the issue, including status and diff --numstat. Identify which read-only commands run on the refresh timer rather than in response to user actions, add the requested configuration there, and verify that those commands no longer query fsmonitor while interactive commands retain their behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
git, go
Domain
cli
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.