mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 16:02:32 +00:00
* Fix rebase race by fetching to private ref before rebasing
`git pull --rebase` is vulnerable to concurrent fetches modifying remote-tracking refs during execution. Fetch to a temporary private ref (refs/orca/rebase/*) first, then rebase from that stable ref to avoid the race condition.
* Fix rebase race by fetching to private ref with timeout
Concurrent fetches can interfere with remote-tracking refs between
fetch and rebase. Use a unique private ref and 60-second timeout to
isolate each rebase operation and prevent hangs on stalled remotes.
Extract gitPullRebaseFromBase to a dedicated module.
* fix rebase race by fetching to private ref with timeouts
Concurrent fetches can replace FETCH_HEAD and remote-tracking refs between
fetch and rebase, causing the rebase to fail. Fetch to a temporary private
ref instead, use --no-write-fetch-head when available (Git 2.29+), and
serialize FETCH_HEAD access for older versions. Add process termination
barriers to ensure proper cleanup and extend timeouts for SSH operations.
* Fix rebase race by fetching to both private and tracking refs
Concurrent fetches between source and rebase can replace remote-tracking refs,
causing rebases to use stale bases. Now fetch to both a private ref and the
remote-tracking ref simultaneously, ensuring the tracking ref stays current.
Also improves process termination for WSL guests with process-group tracking,
fixes process-tree termination timeouts on POSIX, and serializes FETCH_HEAD
operations for linked worktrees through their shared Git directory.
* Add WSL setsid --wait probe and barrier termination timeout
Probe for `setsid --wait` support and fall back to unwrapped execution for BusyBox compatibility. Add a deadline for process termination barriers to prevent hanging when tree termination cannot be verified. Update tests for cross-platform compatibility.
* Add wsl-process-group-termination to WSL invocation allowlist
* Serialize per-worktree git mutations to fix rebase race
Introduce operation locking for each worktree to prevent concurrent
mutations (like rebase) from interfering with each other. Ensures
rebasing a linked worktree doesn't affect the source worktree state.
Add SIGKILL fallback if process termination barriers cannot verify
tree termination.
* Serialize pull and fastForward operations per-worktree
- Extract generic git operation lock to reuse locking pattern
- Refactor existing locks to use the generic implementation
- Apply per-worktree serialization to pull and fastForward to prevent races
* Route WSL group termination through runWslProcess
ce743a4fd0 silenced the wsl-invocation boundary guard by appending
wsl-process-group-termination.ts to the allowlist. That fixture only
grows when the scanner learns to see a spawn it was blind to, and only
shrinks for a migration -- this was new code on this branch, so the
entry was the boundary regressing rather than the guard getting honest.
Migrate the kill instead. terminate() now calls runWslProcess with the
script form (`<shell> -c <script> -- <args>`), which keeps the group id
in $1, so the payload is unchanged. The script is plain POSIX, so it
must not pin shell: 'bash'; it calls only builtins and coreutils on the
default PATH and reads no login environment, so loginPath is 'none'.
wrapGuestArgs() is untouched: its argv is spliced into git/runner.ts's
own wsl.exe invocation, which is a long-standing allowlist entry.
The unit test now mocks runWslProcess and asserts the spec shape --
distro, loginPath, the group id in args -- so a regression back to a raw
spawn fails here as well as at the boundary guard.
* Assert cleanup is defined before accessing properties
64 lines
5.0 KiB
Markdown
64 lines
5.0 KiB
Markdown
# Git Compatibility Policy
|
||
|
||
## Scope
|
||
|
||
Orca executes the user's Git binary on three kinds of execution host: native,
|
||
WSL, and SSH. Each host can have a different Git version, so compatibility
|
||
state must be scoped to the host that actually runs the command.
|
||
|
||
Git 2.25 is the core-workflow compatibility baseline for command selection. It
|
||
is the oldest line that covers Orca's baseline use of porcelain v2, `branch
|
||
--show-current`, `restore`, and sparse checkout. Optional features that need a
|
||
newer Git must degrade safely and cache the missing capability. Orca does not
|
||
currently block older Git at startup, but new command construction should not
|
||
assume features introduced after this baseline.
|
||
|
||
## Capability Rules
|
||
|
||
When a newer Git feature materially improves correctness or performance:
|
||
|
||
1. Keep a baseline-compatible command or parser as the fallback.
|
||
2. Detect rejection with a narrow predicate for that option or subcommand.
|
||
3. Run the preferred command through `GitCapabilityCache` so a rejection is
|
||
remembered for the native host, WSL distro, or SSH provider that produced it.
|
||
4. Retry after the cache interval so an in-place Git upgrade self-heals without
|
||
restarting Orca.
|
||
5. Test the first fallback, later calls that skip the rejected probe, concurrent
|
||
probe coalescing, and execution-host isolation where applicable.
|
||
|
||
Do not branch only on a parsed `git --version`. Vendor builds can backport
|
||
features, and wrappers can report a host version that differs from the binary
|
||
used inside WSL or SSH. A behavior probe plus a precise fallback is the final
|
||
authority.
|
||
|
||
## Current Capabilities
|
||
|
||
| Capability | Preferred behavior | Compatibility behavior |
|
||
| --------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||
| `fetch-no-write-fetch-head` | Fetch a private rebase ref without changing worktree-local `FETCH_HEAD` | Serialize all Orca fetch/pull operations per worktree Git directory before Git 2.29 |
|
||
| `worktree-list-z` | NUL-delimited worktree paths with `prunable` marks | Line-block parser for Git before `worktree list -z` (2.36); the `prunable`/`locked` annotations still parse on Git 2.31–2.35, and a path-existence probe restores `prunable` detection for Git before 2.31 |
|
||
| `rev-parse-path-format` | Absolute repo metadata paths | Resolve legacy relative output against the scanned repo |
|
||
| `for-each-ref-exclude` | Exclude remote HEAD before the output limit | Request extra refs, then filter remote HEAD in Orca |
|
||
| `merge-tree-write-tree` | Derive real-merge conflicts and no-op tree proofs | Omit the conflict summary and keep conservative branch cleanup behavior before Git 2.38 |
|
||
| `merge-tree-merge-base` | Supply the already-resolved merge base | Use the older two-commit `merge-tree --write-tree` form |
|
||
|
||
## Why Not `simple-git`
|
||
|
||
`simple-git` is a process wrapper around the installed Git binary. Its custom
|
||
options and `raw` API pass arguments through to Git, so it cannot make a newer
|
||
flag work on an older binary or choose Orca's semantic fallback automatically.
|
||
It provides version reporting and subprocess queueing, but Orca already needs
|
||
its own WSL/SSH routing, cancellation, tracing, redaction, process cleanup, and
|
||
bounded output handling. Replacing the runner would move—not remove—the
|
||
capability problem.
|
||
|
||
## CI Contract
|
||
|
||
PR checks run the capability contract against real Git 2.25.5, 2.38.1, and
|
||
2.49.1 binaries. This spans the pre-2.29 serialized `FETCH_HEAD` fallback, the transitional
|
||
`merge-tree --write-tree` behavior before `--merge-base`, and current Git.
|
||
|
||
Keep the unit tests alongside that matrix. They cover concurrent probes,
|
||
native/WSL/SSH/relay isolation, and error-stream shapes that a single real
|
||
binary invocation cannot exercise deterministically.
|