Skip to content

fix(windows): git's forward slashes refused every valid clone (+2 test-side platform assumptions) - #28

Merged
Snider merged 1 commit into
mainfrom
lane/win-gitserver-workspace
Aug 8, 2026
Merged

fix(windows): git's forward slashes refused every valid clone (+2 test-side platform assumptions)#28
Snider merged 1 commit into
mainfrom
lane/win-gitserver-workspace

Conversation

@Snider

@Snider Snider commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Three windows-lane failures, one of them a production defect.

agent/workspaceApply refused every acceptance on Windows

It read the integration repo's path back from git rev-parse --path-format=absolute --git-common-dir and compared that raw output against project.ClonePath:

clonePath := core.Trim(commonResult.String())
cloneResult := manager.internalAbsolute(clonePath)
if !cloneResult.OK || cloneResult.String() != project.ClonePath ||
   clonePath != project.ClonePath || core.PathBase(clonePath) != "repo.git" {

Git prints forward slashes on every platform, so C:/…/repo.git never equals a filepath-built C:\…\repo.git — even when both name the same directory. And core.PathBase, matching only the platform separator, reads that raw output as having no separator at all and returns the whole path instead of repo.git. Either check alone was fatal.

It now compares the normalised form, which is what the check meant. The guarantee is unchanged: internalAbsolute has already refused anything escaping the internal root, and PathAbs cleans away .. before the equality test.

This was the root of the cached clone is outside the internal root failures. The commit-hash mismatches sitting beside them in the log were downstreamHEAD simply had not moved, because Apply had already failed.

agent/gitserver — two test-side platform assumptions

CRLF. TestSoftserveGitRoundTrip pushed "private fixture\n" and got back "private fixture\r\n". Git for Windows defaults core.autocrlf on, rewriting LF→CRLF on checkout. gitserverRunGit now pins it off for every invocation. Normalising the comparison instead would have hidden a real corruption behind the same green — the test's claim is that softserve moves bytes through intact.

Mode bits. TestSoftservePermissions asserted 0o700/0o600 and read 0o777/0o666. Windows has no POSIX mode bits; os.Stat synthesises those values whatever the real access control is. The confidentiality being pinned — a private data dir, an unreadable SSH identity — is an ACL question there, which core.FileMode cannot express let alone assert. The three assertions skip on Windows with the reason recorded; service startup above them still runs.

Receipts — macOS

go test -count=1 ./agent/workspace/ ./agent/gitserver/
ok  agent/workspace 135.899s · agent/gitserver 29.617s

GOWORK=off go test -count=1 ./...     exit=0, 176 packages ok
gofmt -l · go vet                      clean

Expectation, stated before the run

Lane state going in: 35 failing packages (run 31251292907, main).

agent/workspace also fails on t.TempDir() cleanup that Windows refuses while a directory is still in use — untouched here and ledgered separately. So I expect this to clear agent/gitserver and not agent/workspace. I'll post the actual number rather than the prediction.

…o test-side assumptions

Three windows-lane failures, one of them a production defect.

agent/workspace — Apply refused every acceptance on Windows. It read the
integration repo's path back from `git rev-parse --path-format=absolute
--git-common-dir` and compared that RAW output against project.ClonePath. Git
prints forward slashes on every platform, so "C:/.../repo.git" never equals a
filepath-built "C:\...\repo.git" even when both name the same directory — and
core.PathBase, matching only the platform separator, read that raw output as
having no separator at all and returned the whole path instead of "repo.git".
Either check alone was fatal. It now compares the normalised form, which is
what the check meant; internalAbsolute has already refused anything escaping
the internal root and PathAbs cleans away ".." before the equality test, so the
guarantee is unchanged. This was the root of the "cached clone is outside the
internal root" failures — the commit-hash mismatches beside them were HEAD
simply not moving because Apply had already failed.

agent/gitserver — two test-side platform assumptions:
- TestSoftserveGitRoundTrip pushed "private fixture\n" and got back
  "private fixture\r\n". Git for Windows defaults core.autocrlf on, rewriting
  LF to CRLF on checkout. gitserverRunGit now pins it off for every
  invocation. Normalising the comparison instead would have hidden a real
  corruption behind the same green — the test's claim is that softserve moves
  bytes through intact.
- TestSoftservePermissions asserted 0o700/0o600. Windows has no POSIX mode
  bits: os.Stat synthesises 0777 for a directory and 0666 for a writable file,
  so it read 0o777/0o666 whatever the real access control was. The
  confidentiality it pins is an ACL question there, which core.FileMode cannot
  express let alone assert, so the assertions skip on Windows with the reason
  recorded. Service startup above them still runs.

Receipts — macOS:
  go test -count=1 ./agent/workspace/ ./agent/gitserver/
  ok  agent/workspace 135.899s · agent/gitserver 29.617s
  GOWORK=off go test -count=1 ./...   exit=0, 176 packages ok
  gofmt -l · go vet: clean

Lane state before this commit: 35 failing packages (main, run 31251292907).
agent/workspace also fails on TempDir cleanup that Windows refuses while a
directory is in use; that is untouched here and ledgered separately, so this
may move agent/gitserver without moving agent/workspace.

Co-Authored-By: Virgil <virgil@lethean.io>
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@Snider, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 28 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5eefe2e2-48f0-4b17-b08c-305abe1d2e18

📥 Commits

Reviewing files that changed from the base of the PR and between 25c2ed4 and 10b2516.

📒 Files selected for processing (2)
  • go/agent/gitserver/softserve_test.go
  • go/agent/workspace/accept.go

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Snider
Snider merged commit 05af590 into main Aug 8, 2026
3 of 4 checks passed
@Snider
Snider deleted the lane/win-gitserver-workspace branch August 8, 2026 10:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant