zai-org / zai-org/feedback

[Bug] Periodic git.refresh rewrites .git/index without GIT_OPTIONAL_LOCKS=0 - sync-loop hazard for repos in cloud-synced folders

Open
#552 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

priority: P2
Dominant language
No language data
Stars
22
Forks
1
PR merge metrics
No merged PRs in 30d

Description

Environment
  • ZCode Desktop 3.10.2.6414, Windows 11
  • Workspace = a git repo whose folder is also synced by a cloud-sync client (the whole folder incl. .git is mirrored across several PCs)
Summary

ZCode's Git integration spawns read-only git commands without GIT_OPTIONAL_LOCKS=0, so git status rewrites .git/index whenever the stat cache is stale. Since refreshes are triggered by window focus, a file watcher, and background polling (observed while a mobile web-remote session was paired), ZCode rewrites .git/index every ~1-3 minutes even when the user does nothing.

Evidence (captured 2026-09-06)
  1. Process capture - git.exe spawned by the ZCode host process:
git status --porcelain=v2 --branch --untracked-files=normal -z
git diff --cached --numstat -z --find-renames --
git diff --numstat -z --find-renames --
git config --show-scope --show-origin --get user.name / user.email

.git/index mtime changed within the same capture window as the spawn.

  1. Host-log correlation - ZCode's own log shows the refresh RPC completing ~10 ms after the index rewrite:
23:06:27.428  .git/index written (file mtime observed)
23:06:27.439  [zcode-host] [rpc:call] git.refresh OK (124.9ms)
  1. Triggers confirmed independently:
  • Window focus: switching to the ZCode window -> index rewritten 19 s later
  • File watcher: touching a tracked file -> index rewritten ~1-2 min later
  • Idle polling: git.refresh every ~1-3 min with zero user input while a paired web-remote session was online (e.g. a refresh at 23:07:48 with nothing touched)
  1. Control experiment - VS Code built-in Git extension on the same repo under the same stale-stat conditions, captured git status -z -uall: .git/index was not rewritten. (VS Code spawns git with GIT_OPTIONAL_LOCKS=0 for read-only commands - the standard practice for exactly this reason.)
Impact

For a plain local repo this is invisible. For a repo inside a cloud-synced folder it creates a self-sustaining loop across machines:

machine A rewrites index -> sync client uploads (~437 KB per rewrite for a mid-size repo) -> machine B receives the replaced index -> B's index stat cache becomes fully stale -> B's ZCode rewrites it on next refresh -> uploads -> back to A ...

In our case (repo synced across machines) the sustained loop consumed a 1 GB/month upload quota in about two days (~55 rewrites/hour at peak).

Suggested fix

Set GIT_OPTIONAL_LOCKS=0 in the environment when spawning read-only git commands (status / diff / log / for-each-ref ...), or pass --no-optional-locks to git status. The SCM view stays correct while background refreshes never touch the index.

Reproduction
  1. Open a git repo as a ZCode workspace; optionally pair the mobile web-remote (speeds up the refresh cadence).
  2. Touch any tracked file (or simply focus the ZCode window).
  3. Watch .git/index mtime - it changes within seconds to minutes, parented by the ZCode host process.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the Git integration's git.refresh entry point and the process-spawn paths for the listed read-only commands: status, diff, log, and for-each-ref. Reproduce the stale-stat case while watching .git/index mtime and host logs. Done means background refreshes leave the index unchanged while the SCM view remains correct.

Written by the indexing model from the issue text.

Assessment

Tech stack
git
Domain
devtools, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.