[PR #521] Fix Windows extended-length path prefix in hook commands #533

Closed
opened 2026-03-02 04:13:54 +03:00 by kerem · 0 comments
Owner

Original Pull Request: https://github.com/git-ai-project/git-ai/pull/521

State: closed
Merged: Yes


Fix Windows extended-length path prefix in hook commands

Summary

Fixes #519. On Windows, std::fs::canonicalize() returns paths with the \\?\ extended-length prefix (e.g. \\?\C:\Users\USERNAME\.git-ai\bin\git-ai.exe). This prefix was leaking into hook command strings for all agent installers (Claude Code, Cursor, Gemini, Droid, Codex, OpenCode) because get_current_binary_path() passed the canonicalized path through unchanged.

The fix adds a clean_path() utility that strips the \\?\ prefix and applies it in get_current_binary_path(), so all downstream consumers get clean paths.

Review & Testing Checklist for Human

  • Windows CI must pass — this fix was developed on Linux; the actual canonicalize()\\?\ behavior only occurs on Windows. Confirm the Windows CI job passes end-to-end.
  • Verify clean_path doesn't affect UNC paths — UNC paths start with \\server\share\... (not \\?\), so they should be unaffected, but worth a quick sanity check that the strip_prefix(r"\\?\") is specific enough.
  • Spot-check that no other callers of get_current_binary_path() depend on the \\?\ prefix — e.g. install_hooks.rs uses it; the prefix removal should be safe everywhere since \\?\ paths are strictly a Windows API concern and not needed for command strings or file operations.
  • Recommend manual test: On a Windows machine, run git-ai install-hooks and verify the resulting hook commands in .claude/settings.json (or Cursor/Gemini equivalents) contain a clean path like C:\Users\...\git-ai.exe without the \\?\ prefix.

Notes

  • Regression tests were added for clean_path itself (3 tests in utils.rs) and for claude_code and cursor agents specifically. Other agents (gemini, droid, codex, opencode) are also fixed by the centralized get_current_binary_path() change but don't have dedicated regression tests.
  • clean_path is not gated behind #[cfg(windows)] so the tests run on all platforms. On non-Windows, canonicalize() never produces the \\?\ prefix, so the function is effectively a no-op in production on Linux/macOS.

Link to Devin run: https://app.devin.ai/sessions/a4d19f1733f54950afe9bb53488dd521
Requested by: @svarlamov


Open with Devin
**Original Pull Request:** https://github.com/git-ai-project/git-ai/pull/521 **State:** closed **Merged:** Yes --- # Fix Windows extended-length path prefix in hook commands ## Summary Fixes #519. On Windows, `std::fs::canonicalize()` returns paths with the `\\?\` extended-length prefix (e.g. `\\?\C:\Users\USERNAME\.git-ai\bin\git-ai.exe`). This prefix was leaking into hook command strings for all agent installers (Claude Code, Cursor, Gemini, Droid, Codex, OpenCode) because `get_current_binary_path()` passed the canonicalized path through unchanged. The fix adds a `clean_path()` utility that strips the `\\?\` prefix and applies it in `get_current_binary_path()`, so all downstream consumers get clean paths. ## Review & Testing Checklist for Human - [ ] **Windows CI must pass** — this fix was developed on Linux; the actual `canonicalize()` → `\\?\` behavior only occurs on Windows. Confirm the Windows CI job passes end-to-end. - [ ] **Verify `clean_path` doesn't affect UNC paths** — UNC paths start with `\\server\share\...` (not `\\?\`), so they should be unaffected, but worth a quick sanity check that the `strip_prefix(r"\\?\")` is specific enough. - [ ] **Spot-check that no other callers of `get_current_binary_path()` depend on the `\\?\` prefix** — e.g. `install_hooks.rs` uses it; the prefix removal should be safe everywhere since `\\?\` paths are strictly a Windows API concern and not needed for command strings or file operations. - [ ] **Recommend manual test**: On a Windows machine, run `git-ai install-hooks` and verify the resulting hook commands in `.claude/settings.json` (or Cursor/Gemini equivalents) contain a clean path like `C:\Users\...\git-ai.exe` without the `\\?\` prefix. ### Notes - Regression tests were added for `clean_path` itself (3 tests in `utils.rs`) and for claude_code and cursor agents specifically. Other agents (gemini, droid, codex, opencode) are also fixed by the centralized `get_current_binary_path()` change but don't have dedicated regression tests. - `clean_path` is not gated behind `#[cfg(windows)]` so the tests run on all platforms. On non-Windows, `canonicalize()` never produces the `\\?\` prefix, so the function is effectively a no-op in production on Linux/macOS. Link to Devin run: https://app.devin.ai/sessions/a4d19f1733f54950afe9bb53488dd521 Requested by: @svarlamov <!-- devin-review-badge-begin --> --- <a href="https://app.devin.ai/review/git-ai-project/git-ai/pull/521" target="_blank"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1"> <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open with Devin"> </picture> </a> <!-- devin-review-badge-end -->
kerem 2026-03-02 04:13:54 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/git-ai#533
No description provided.