Summary
In a bind-mode container (Docker Desktop on macOS, virtiofs/gRPC-FUSE), git rebase (and checkout/merge/stash pop) intermittently aborts with:
error: Your local changes to the following files would be overwritten by merge:
<files that differ between the branch and the rebase target>
Please commit your changes or stash them before you merge.
Aborting
…even though git status and git diff report the worktree clean. Not a real conflict, not pre-commit.
Root cause
git's default core.checkStat=normal compares all stat fields (ino, ctime, uid, gid, mtime, size). The clawker bind workspace crosses the macOS host → container boundary over virtiofs, which synthesizes/remaps ino + ctime, and the container claude UID ≠ host UID (the known "virtiofs masks UID/GID" behavior). The git index's recorded stat no longer matches what the container reads, so git flags every file that differs between the branch and the rebase onto as phantom stat-dirty. git status masks this (it re-hashes content → reports clean), but rebase's verify_uptodate refuses to overwrite "modified" files and aborts before the content re-hash.
Intermittent because it only triggers on operations doing verify_uptodate without a prior content re-hash, and only after stat drift accumulates (host-side git ops, container restarts).
Evidence (decisive: stat, not content)
$ git diff # empty throughout
$ git rebase main # fails: "local changes would be overwritten"
$ git -c core.checkStat=minimal rebase main
Successfully rebased and updated refs/heads/<branch>.
core.checkStat=minimal compares only mtime+size — the fields virtiofs keeps stable — so the phantom-dirty disappears. Host-side rebase also works (native APFS, stable stat, matching UID).
Proposed fix
clawker already injects git config via GIT_CONFIG_COUNT / GIT_CONFIG_KEY_n / GIT_CONFIG_VALUE_n env vars in internal/docker/env.go (currently for gpg.program), which overrides all file-level config including the bind-mounted .git/config. Extend that same injection — at least for bind workspace mode — to add:
core.checkStat=minimal
core.trustctime=false
This is env-based (no file mutation), overrides every config level, and is harmless in snapshot mode too. Requires generalizing the currently-hardcoded GIT_CONFIG_COUNT=1 into a counter so it composes with the existing gpg.program entry.
Scope / classification
Underlying cause is a git + Docker-bind-on-macOS interaction, not clawker code doing something wrong — but clawker chooses bind mode + UID remap and owns the container git config, so the mitigation belongs here. Affects any user doing rebase/checkout/merge inside a bind-mode container; reported as recurring.
Workaround (today)
Inside the container: git config core.checkStat minimal && git config core.trustctime false (repo-local or global), or perform the rebase on the host.
Summary
In a
bind-mode container (Docker Desktop on macOS, virtiofs/gRPC-FUSE),git rebase(andcheckout/merge/stash pop) intermittently aborts with:…even though
git statusandgit diffreport the worktree clean. Not a real conflict, not pre-commit.Root cause
git's default
core.checkStat=normalcompares all stat fields (ino,ctime,uid,gid,mtime,size). The clawker bind workspace crosses the macOS host → container boundary over virtiofs, which synthesizes/remapsino+ctime, and the containerclaudeUID ≠ host UID (the known "virtiofs masks UID/GID" behavior). The git index's recorded stat no longer matches what the container reads, so git flags every file that differs between the branch and the rebaseontoas phantom stat-dirty.git statusmasks this (it re-hashes content → reports clean), but rebase'sverify_uptodaterefuses to overwrite "modified" files and aborts before the content re-hash.Intermittent because it only triggers on operations doing
verify_uptodatewithout a prior content re-hash, and only after stat drift accumulates (host-side git ops, container restarts).Evidence (decisive: stat, not content)
core.checkStat=minimalcompares onlymtime+size— the fields virtiofs keeps stable — so the phantom-dirty disappears. Host-side rebase also works (native APFS, stable stat, matching UID).Proposed fix
clawker already injects git config via
GIT_CONFIG_COUNT/GIT_CONFIG_KEY_n/GIT_CONFIG_VALUE_nenv vars ininternal/docker/env.go(currently forgpg.program), which overrides all file-level config including the bind-mounted.git/config. Extend that same injection — at least forbindworkspace mode — to add:core.checkStat=minimalcore.trustctime=falseThis is env-based (no file mutation), overrides every config level, and is harmless in snapshot mode too. Requires generalizing the currently-hardcoded
GIT_CONFIG_COUNT=1into a counter so it composes with the existinggpg.programentry.Scope / classification
Underlying cause is a git + Docker-bind-on-macOS interaction, not clawker code doing something wrong — but clawker chooses bind mode + UID remap and owns the container git config, so the mitigation belongs here. Affects any user doing rebase/checkout/merge inside a bind-mode container; reported as recurring.
Workaround (today)
Inside the container:
git config core.checkStat minimal && git config core.trustctime false(repo-local or global), or perform the rebase on the host.