Skip to content

Add SSH transport support#54

Merged
Soph merged 11 commits into
mainfrom
soph/ssh-transport
May 18, 2026
Merged

Add SSH transport support#54
Soph merged 11 commits into
mainfrom
soph/ssh-transport

Conversation

@Soph
Copy link
Copy Markdown
Contributor

@Soph Soph commented May 14, 2026

Summary

Adds SSH transport support to git-sync using the local ssh binary.

This replaces the stalled SSH draft with a fresh implementation from current main.

What changed

  • extract a transport interface and rename the existing HTTP transport to HTTPConn
  • add SSHConn using one ssh process per logical RPC
  • support ssh://, SCP-style git@host:path.git, and git+ssh:// remotes
  • honor SSH config-driven user/key behavior by not forcing a default git@ user
  • fail early with a clear error when ssh is not available on PATH
  • warn explicitly that --progress / --stats do not yet expose byte-counted SSH throughput
  • document SSH support and its current caveats

Implementation notes

The key transport fix versus the old draft is per-RPC execution. git-sync makes multiple logical RPCs per endpoint in normal flows, especially under protocol v2 and batching, so a single long-lived SSH process is the wrong model.

Each RequestInfoRefs / PostRPCStreamBody call now shells out independently via exec.CommandContext, which also fixes the earlier context-handling and stderr-race issues.

The SSH transport trims the leading advertised-refs section emitted by fresh upload-pack / receive-pack invocations before exposing the actual command stream.

Tests

Added and updated coverage for:

  • transport seam refactor across gitproto, strategies, and syncer
  • SSH command construction for URL forms, ports, and ~-prefixed SCP paths
  • repeated SSH RPC calls on the same logical endpoint
  • SSH cancellation behavior for both discovery and stream RPCs
  • end-to-end sync over an SSH shim using real git-upload-pack / git-receive-pack

Verified locally with:

  • go test ./internal/gitproto ./internal/syncer -run 'TestSSHConn|TestRun_IntegrationSyncOverSSHShimV2|TestSSHStatsWarning' -count=1
  • go test ./internal/gitproto ./internal/strategy/... ./internal/syncer -run '^$'

Remaining caveat

SSH sync works, but --progress and --stats currently omit byte-counted SSH transfer throughput. The PR warns explicitly rather than silently reporting misleading zero-byte stats.

Closes #36


Note

Medium Risk
Adds a new SSH transport and refactors core fetch/push/session plumbing to use an interface-based connection, which touches critical sync paths and could affect remote compatibility and error handling across both HTTP and SSH.

Overview
git-sync now supports SSH remotes by introducing a transport-agnostic gitproto.Conn interface, renaming the existing smart-HTTP transport to HTTPConn, and adding a new SSHConn that shells out to the local ssh binary per RPC (discovery and streaming RPCs).

Core fetch/push/refs code and all strategies (bootstrap, incremental, replicate, materialized) are updated to accept Conn instead of *Conn, with progress output routed via Conn.ProgressWriter() and session teardown now calling Conn.Close().

The CLI/session layer (syncer) now detects ssh/git+ssh (and SCP-style) URLs to build SSHConn, prints a warning that --progress/--stats omit SSH byte throughput, and docs/tests are updated with SSH usage notes plus unit and integration coverage for SSH invocation, context cancellation, and end-to-end sync over an SSH shim.

Reviewed by Cursor Bugbot for commit ceeddf9. Configure here.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit ceeddf9. Configure here.

Comment thread internal/gitproto/ssh.go Outdated
@Soph Soph requested a review from nodo May 14, 2026 19:23
nodo
nodo previously approved these changes May 18, 2026
Copy link
Copy Markdown
Collaborator

@nodo nodo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just added a minor comment, not a blocker.

Comment thread internal/gitproto/refs.go Outdated
Comment on lines +102 to +104
return strings.Contains(msg, "Invalid command:") &&
strings.Contains(msg, "GIT_PROTOCOL='version=2'") &&
strings.Contains(msg, "git-upload-pack")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 not a blocker, but I wonder if we could do a pass and handle these better. e.g. is this specific to github?

Soph added 11 commits May 18, 2026 16:12
Entire-Checkpoint: 9dc3927cec43
Entire-Checkpoint: f9da8767b8db
Entire-Checkpoint: 5f03021cd910
Entire-Checkpoint: 338b03e03d07
Entire-Checkpoint: 4dd13848aefc
Entire-Checkpoint: 5f82375c7a8a
Entire-Checkpoint: 557dfe4672e0
Entire-Checkpoint: ae52adb63cec
@Soph Soph force-pushed the soph/ssh-transport branch from d9431a8 to 3b30f87 Compare May 18, 2026 14:21
@Soph Soph merged commit 42b9cfe into main May 18, 2026
3 checks passed
@Soph Soph deleted the soph/ssh-transport branch May 18, 2026 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Add support for SSH authentication

2 participants