Repository navigation
Run file explorer git status without optional locks - #7173
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
Next review available in: 2 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThe GitFileStatus and GitStatusProvider implementation is moved from FileExplorerStore.swift into a new standalone Sources/GitStatusProvider.swift, with non-locking Git environment settings preserved. The Xcode project is updated to reference the new source file and a new test file, which verifies status queries do not modify the git index. ChangesGitStatusProvider extraction and non-locking status queries
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant FileExplorerStore
participant GitStatusProvider
participant GitProcess
participant SSHProcess
FileExplorerStore->>GitStatusProvider: fetchStatus(directory)
GitStatusProvider->>GitProcess: git rev-parse --show-toplevel (non-locking env)
GitProcess-->>GitStatusProvider: repoRoot
GitStatusProvider->>GitProcess: git status --porcelain
GitProcess-->>GitStatusProvider: porcelain output
GitStatusProvider-->>FileExplorerStore: absolute-path status map
FileExplorerStore->>GitStatusProvider: fetchStatusSSH(directory, destination)
GitStatusProvider->>SSHProcess: remote repo root + git status --porcelain
SSHProcess-->>GitStatusProvider: marker-split output
GitStatusProvider-->>FileExplorerStore: absolute-path status map
Related issues: Suggested labels: swift, tests, xcodeproj Suggested reviewers: (none specified) 🐰 A rabbit dug the status code free, Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error, 1 warning)
✅ Passed checks (23 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR fixes the file-explorer git status probe from acquiring optional git locks (rewriting
Confidence Score: 5/5Safe to merge; the changes are a well-contained extraction and correctness fix with no regressions on the core git-status path. The core logic is correct and well-covered: three real-filesystem tests (index byte-identity, quoted filenames, sibling filtering) plus two fake-executable tests for environment propagation and type-T/UU mapping. The pipe-before-waitUntilExit ordering in the new runGit/runSSH is the safe pattern. The only gap is that the fake-git case match in one test ignores the -z argument, so a future removal of -z would go undetected by that test — a test coverage nit, not a production defect. cmuxTests/FileExplorerGitStatusProviderTests.swift — the statusQueryMapsTypeChangedAndUnmergedEntries fake-git script case match should be tightened to include -z. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant FES as FileExplorerStore
participant GSP as GitStatusProvider
participant Git as /usr/bin/git<br/>(GIT_OPTIONAL_LOCKS=0)
participant SSH as /usr/bin/ssh
Note over FES: DispatchQueue.global(.utility)
alt Local filesystem
FES->>GSP: fetchStatus(directory:)
GSP->>Git: rev-parse --show-toplevel
Git-->>GSP: repoRoot
GSP->>Git: "status --porcelain=v1 -z"
Git-->>GSP: NUL-delimited entries
GSP->>GSP: parseGitStatus() segment-aware path filter
GSP-->>FES: [absolutePath: GitFileStatus]
else Remote SSH
FES->>GSP: fetchStatusSSH(directory:destination:...)
GSP->>SSH: "cd && env GIT_OPTIONAL_LOCKS=0 git rev-parse && echo sentinel && env git status --porcelain=v1 -z"
SSH-->>GSP: repoRoot + sentinel + NUL-delimited entries
GSP->>GSP: split on sentinel then parseGitStatus()
GSP-->>FES: [absolutePath: GitFileStatus]
end
FES->>FES: "DispatchQueue.main.async gitStatusByPath = status"
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant FES as FileExplorerStore
participant GSP as GitStatusProvider
participant Git as /usr/bin/git<br/>(GIT_OPTIONAL_LOCKS=0)
participant SSH as /usr/bin/ssh
Note over FES: DispatchQueue.global(.utility)
alt Local filesystem
FES->>GSP: fetchStatus(directory:)
GSP->>Git: rev-parse --show-toplevel
Git-->>GSP: repoRoot
GSP->>Git: "status --porcelain=v1 -z"
Git-->>GSP: NUL-delimited entries
GSP->>GSP: parseGitStatus() segment-aware path filter
GSP-->>FES: [absolutePath: GitFileStatus]
else Remote SSH
FES->>GSP: fetchStatusSSH(directory:destination:...)
GSP->>SSH: "cd && env GIT_OPTIONAL_LOCKS=0 git rev-parse && echo sentinel && env git status --porcelain=v1 -z"
SSH-->>GSP: repoRoot + sentinel + NUL-delimited entries
GSP->>GSP: split on sentinel then parseGitStatus()
GSP-->>FES: [absolutePath: GitFileStatus]
end
FES->>FES: "DispatchQueue.main.async gitStatusByPath = status"
Reviews (7): Last reviewed commit: "Address git status provider review feedb..." | Re-trigger Greptile |
There was a problem hiding this comment.
3 issues found across 5 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cmuxTests/FileExplorerGitStatusProviderTests.swift`:
- Around line 46-66: Simplify runGit by replacing the `#expect` plus manual
GitSetupFailure throw with a single `#require` boolean check that includes the
same failure message; use the runGit helper as the target and remove the
now-unused GitSetupFailure type entirely.
In `@Sources/GitStatusProvider.swift`:
- Around line 62-68: The status filter in GitStatusProvider currently uses a
simple hasPrefix(explorerRoot) check, which can incorrectly include sibling
paths that only share the same name prefix. Update the absolutePath containment
check to use the same boundary-aware contract as
FileExplorerStore.path(_:isContainedIn:)—only accept paths that are exactly the
explorer root or start with the root plus a path separator—then keep the
existing statusMap assignment and markParentDirectories call for truly contained
paths.
- Line 12: The remote git invocation in GitStatusProvider currently relies on
shell-specific variable assignment, which breaks on csh/tcsh remotes. Update the
nonLockingRemoteGitCommand constant to invoke git through env so the
nonLockingGitEnvironmentKey is set in a shell-agnostic way, and keep the change
localized to the GitStatusProvider command-building logic.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4c9914f4-de8f-4886-b262-9aae55c58f2c
📒 Files selected for processing (4)
Sources/FileExplorerStore.swiftSources/GitStatusProvider.swiftcmux.xcodeproj/project.pbxprojcmuxTests/FileExplorerGitStatusProviderTests.swift
💤 Files with no reviewable changes (1)
- Sources/FileExplorerStore.swift
There was a problem hiding this comment.
3 issues found across 5 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
Summary
GIT_OPTIONAL_LOCKS=0for file explorer git status probes, including the remote SSH status command path.git status --porcelain=v1 -zoutput so quoted, escaped, and whitespace-heavy filenames keep the correct file explorer badges.Repro notes
git status --porcelainrewrite.git/index.GIT_OPTIONAL_LOCKS=0left.git/indexbyte-identical, which is the lock-free background-refresh behavior cmux needs.Validation
git diff --checkpython3 scripts/swift_file_length_budget.py --repo-root . --budget .github/swift-file-length-budget.tsv./scripts/lint-pbxproj-test-wiring.sh./scripts/check-pbxproj.shFixes #4779
Supersedes #4805 — thanks @SpencerJung for the original diagnosis and one-line local fix; this PR extends it to the SSH variant and adds regression coverage.