Complete Git-over-SSH with safe push and combined synchronization through the server-side git-receive-pack service.
Scope
Open a verified, authenticated russh exec channel for git-receive-pack using the same endpoint, identity, host-key, quoting, cancellation, and diagnostic rules as upload-pack.
Reuse the existing storage-owned receive-pack advertisement validation, ancestry/non-fast-forward check, pack construction, capability negotiation, report-status parsing, and remote-tracking update logic without HTTP framing assumptions.
Support new-branch and fast-forward push plus the push half of sync for both SSH URL spellings.
Keep pull-before-push ordering for sync; never push after a failed/cancelled/conflicted pull.
Half-close stdin only after the complete request, drain protocol output and bounded stderr, require an unambiguous successful service status, and do not claim success solely because the socket closed.
Map server rejection, unpack failure, ref rejection, non-fast-forward, channel exit/signal, disconnect, cancellation, host/auth failure, and ambiguous post-send failure to typed recoverable states.
On an ambiguous failure after bytes may have reached the server, leave the local repository valid and require a fresh fetch/status before retrying; never blindly replay a push.
Preserve dirty-worktree refusal and prevent remote tracking refs from advancing until the server has confirmed the update.
Tests and verification
Extend the pure-Rust in-process SSH Git fixture with receive-pack behavior; no installed Git/OpenSSH binaries may be required.
Cover empty-remote push, ordinary fast-forward push, already-current push, non-fast-forward rejection, server ref policy rejection, unpack failure, malformed status, early EOF, signal/non-zero exit, cancellation before and after send, ambiguous disconnect, and sync pull failure.
Inspect emitted pkt-lines, object closure, pack checksum, selected ref, service command, and remote-tracking update.
Prove failures do not corrupt objects, refs, index, worktree, or unrelated staged state and do not leak credentials/key material.
Run all repository-required Rust gates.
Acceptance criteria
Push and full pull-then-push synchronization work over both requested SSH URL forms.
A remote ref is updated only through confirmed receive-pack success; non-fast-forward and ambiguous outcomes fail safely.
Upload-pack and receive-pack share one storage-owned SSH trust/auth/session policy.
No local Git, SSH, shell, helper, or transport process is launched.
Depends on SSH upload-pack plus the authentication/host-verification issue in this milestone.
## Goal
Complete Git-over-SSH with safe push and combined synchronization through the server-side `git-receive-pack` service.
## Scope
- Open a verified, authenticated `russh` exec channel for `git-receive-pack` using the same endpoint, identity, host-key, quoting, cancellation, and diagnostic rules as upload-pack.
- Reuse the existing storage-owned receive-pack advertisement validation, ancestry/non-fast-forward check, pack construction, capability negotiation, report-status parsing, and remote-tracking update logic without HTTP framing assumptions.
- Support new-branch and fast-forward push plus the push half of `sync` for both SSH URL spellings.
- Keep pull-before-push ordering for `sync`; never push after a failed/cancelled/conflicted pull.
- Half-close stdin only after the complete request, drain protocol output and bounded stderr, require an unambiguous successful service status, and do not claim success solely because the socket closed.
- Map server rejection, unpack failure, ref rejection, non-fast-forward, channel exit/signal, disconnect, cancellation, host/auth failure, and ambiguous post-send failure to typed recoverable states.
- On an ambiguous failure after bytes may have reached the server, leave the local repository valid and require a fresh fetch/status before retrying; never blindly replay a push.
- Preserve dirty-worktree refusal and prevent remote tracking refs from advancing until the server has confirmed the update.
## Tests and verification
- Extend the pure-Rust in-process SSH Git fixture with receive-pack behavior; no installed Git/OpenSSH binaries may be required.
- Cover empty-remote push, ordinary fast-forward push, already-current push, non-fast-forward rejection, server ref policy rejection, unpack failure, malformed status, early EOF, signal/non-zero exit, cancellation before and after send, ambiguous disconnect, and sync pull failure.
- Inspect emitted pkt-lines, object closure, pack checksum, selected ref, service command, and remote-tracking update.
- Prove failures do not corrupt objects, refs, index, worktree, or unrelated staged state and do not leak credentials/key material.
- Run all repository-required Rust gates.
## Acceptance criteria
- Push and full pull-then-push synchronization work over both requested SSH URL forms.
- A remote ref is updated only through confirmed receive-pack success; non-fast-forward and ambiguous outcomes fail safely.
- Upload-pack and receive-pack share one storage-owned SSH trust/auth/session policy.
- No local Git, SSH, shell, helper, or transport process is launched.
Depends on SSH upload-pack plus the authentication/host-verification issue in this milestone.
hugo
added this to the 07 - Pure-Rust Git-over-SSH remotes milestone 2026-08-24 20:17:07 +00:00
Implemented and pushed in 76e707f6457f3a0d8b46f3a49beb9b5d16162046.
Added pure-Rust git-receive-pack over the same verified/authenticated Russh session policy as upload-pack, including shared command/path quoting.
Reused the storage-owned receive advertisement, fast-forward, pack construction, capability, report-status, and tracking logic for HTTPS and SSH. SSH sends the complete request, half-closes input, drains bounded output/stderr, and requires explicit protocol plus channel success.
Added typed unpack/ref rejection and ambiguous post-send outcomes; remote tracking advances only after confirmed success. Synchronization remains pull-first and never opens receive-pack after a failed pull.
Added an in-process pure-Rust SSH fixture covering new branch, fast-forward, already current, non-fast-forward, policy rejection, unpack failure, malformed status, EOF, nonzero/signal, disconnect, cancellation before/after send, host/auth failure, both SSH URL spellings, and failed-pull ordering. Tests inspect the service command, ref command, pack v2/object count/checksum, credential non-disclosure, and local/tracking state preservation.
SSH-feature all-target check, clippy, and full test suite
Release macOS bundle built and validated in the actual IronStorage desktop UI: existing vault loaded; Git status showed main, HTTPS origin, 0 ahead / 0 behind, clean worktree. No Apple app sources changed.
cargo audit: existing RUSTSEC-2023-0071 on rsa 0.9.10 and 0.10.0-rc.18 (medium, no fixed upgrade), plus 15 allowed transitive warnings; this issue added no dependencies.
Implemented and pushed in `76e707f6457f3a0d8b46f3a49beb9b5d16162046`.
- Added pure-Rust `git-receive-pack` over the same verified/authenticated Russh session policy as upload-pack, including shared command/path quoting.
- Reused the storage-owned receive advertisement, fast-forward, pack construction, capability, report-status, and tracking logic for HTTPS and SSH. SSH sends the complete request, half-closes input, drains bounded output/stderr, and requires explicit protocol plus channel success.
- Added typed unpack/ref rejection and ambiguous post-send outcomes; remote tracking advances only after confirmed success. Synchronization remains pull-first and never opens receive-pack after a failed pull.
- Added an in-process pure-Rust SSH fixture covering new branch, fast-forward, already current, non-fast-forward, policy rejection, unpack failure, malformed status, EOF, nonzero/signal, disconnect, cancellation before/after send, host/auth failure, both SSH URL spellings, and failed-pull ordering. Tests inspect the service command, ref command, pack v2/object count/checksum, credential non-disclosure, and local/tracking state preservation.
Verification:
- `cargo fmt --all -- --check`
- `RUSTFLAGS="-D warnings" cargo check --workspace --all-targets`
- `cargo clippy --workspace --all-targets -- -D warnings`
- `cargo test --workspace`
- SSH-feature all-target check, clippy, and full test suite
- Release macOS bundle built and validated in the actual IronStorage desktop UI: existing vault loaded; Git status showed `main`, HTTPS `origin`, 0 ahead / 0 behind, clean worktree. No Apple app sources changed.
- `cargo audit`: existing RUSTSEC-2023-0071 on `rsa` 0.9.10 and 0.10.0-rc.18 (medium, no fixed upgrade), plus 15 allowed transitive warnings; this issue added no dependencies.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Goal
Complete Git-over-SSH with safe push and combined synchronization through the server-side
git-receive-packservice.Scope
russhexec channel forgit-receive-packusing the same endpoint, identity, host-key, quoting, cancellation, and diagnostic rules as upload-pack.syncfor both SSH URL spellings.sync; never push after a failed/cancelled/conflicted pull.Tests and verification
Acceptance criteria
Depends on SSH upload-pack plus the authentication/host-verification issue in this milestone.
Implemented and pushed in
76e707f6457f3a0d8b46f3a49beb9b5d16162046.git-receive-packover the same verified/authenticated Russh session policy as upload-pack, including shared command/path quoting.Verification:
cargo fmt --all -- --checkRUSTFLAGS="-D warnings" cargo check --workspace --all-targetscargo clippy --workspace --all-targets -- -D warningscargo test --workspacemain, HTTPSorigin, 0 ahead / 0 behind, clean worktree. No Apple app sources changed.cargo audit: existing RUSTSEC-2023-0071 onrsa0.9.10 and 0.10.0-rc.18 (medium, no fixed upgrade), plus 15 allowed transitive warnings; this issue added no dependencies.