Skip to content

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

Description

@joshgoebel

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/<name>/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/<name>/fsmonitor--daemon/cookies/, showing the cookie churn firing in lockstep with lazygit's refresh interval, and stopping entirely when lazygit quits.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions