Fetch and push git repositories directly between machines — no hosting service, no daemon, no port forwarding, no VPN.
# machine A
$ git push iroh:// main
git clone iroh://endpoint2rgc…/8f00ba4… # <- prints this, waits
# machine B, anywhere in the world
$ git clone iroh://endpoint2rgc…/8f00ba4… # A's push completes
git-remote-iroh is a git remote helper that tunnels git's native smart
protocol over iroh — QUIC connections with NAT hole-punching, relay
fallback, and end-to-end encryption. Because the real git upload-pack and
git receive-pack run on each end, transfers get full want/have negotiation
and server-built thin packs: fetching and pushing over iroh:// moves
exactly the same bytes as over ssh://, between any two machines that can
each reach the internet (or each other).
Prebuilt binary (Linux, Apple-silicon macOS; installs to ~/.local/bin):
curl -fsSL https://raw.githubusercontent.com/magik6k/git-remote-iroh/main/install.sh | sh
With cargo, from source (any platform, rust ≥ 1.91):
cargo install --git https://github.com/magik6k/git-remote-iroh
Or grab a binary from the releases page. However it gets there — once
git-remote-iroh is on PATH, git handles iroh:// URLs by itself.
git push iroh:// (with a bare URL) offers the repository for a single
fetch. It prints a URL, blocks until the other side has pulled, and then
reports the push as done:
# machine A
$ git push iroh:// main
# machine B — either of:
$ git clone iroh://endpoint…/8f00ba4… myrepo
$ git pull iroh://endpoint…/8f00ba4… main
Nothing is stored anywhere in between: the two machines talk directly (through an iroh relay only when hole-punching fails, still encrypted end to end).
# machine A
$ git-remote-iroh serve --writable
iroh://endpoint2rgc…/8f00ba4…
# machine B
$ git remote add laptop iroh://endpoint2rgc…/8f00ba4…
$ git fetch laptop
$ git push laptop main
The repository's identity lives in .git/iroh/, so the URL stays the same
across serve sessions — set it up as a named remote once and sync whenever
serve is running on the other side.
| Command | Description |
|---|---|
git-remote-iroh serve | Serve the current repository until Ctrl-C. |
serve --writable | Also accept pushes (git receive-pack). |
serve --once | Exit after the first successful session. |
serve --ephemeral | Throwaway identity; the URL only works for this session. |
git-remote-iroh id | Print the repo's stable short URL (dials via iroh discovery while serve runs). |
--writable). Share it like a password..git/iroh/. Delete that directory (or use --ephemeral) to rotate the
URL.git config receive.denyCurrentBranch updateInstead (serve prints a
hint). Pushing to other branches, or into a bare repo, just works.git push iroh:// reporting ok means one peer fetched the
offered refs — a way to hand a repo over, not durable storage.serve binds an iroh endpoint and prints iroh://<ticket>/<secret>. When
git sees an iroh:// URL it invokes this helper, which advertises the
connect capability, dials the ticket, authenticates with the secret, and
then simply shovels bytes between git and the git upload-pack /
git receive-pack spawned on the serving side. Offer mode
(git push iroh://) is sugar that serves the repository for exactly one
fetch. The stream-bridging approach follows n0's dumbpipe.
Licensed under the Apache License, Version 2.0.
6 commits
Hacker News (1)
Rust
90.9%
Shell
9.1%
Fetch and push git repositories directly between machines — no hosting service, no daemon, no port forwarding, no VPN.
# machine A
$ git push iroh:// main
git clone iroh://endpoint2rgc…/8f00ba4… # <- prints this, waits
# machine B, anywhere in the world
$ git clone iroh://endpoint2rgc…/8f00ba4… # A's push completes
git-remote-iroh is a git remote helper that tunnels git's native smart
protocol over iroh — QUIC connections with NAT hole-punching, relay
fallback, and end-to-end encryption. Because the real git upload-pack and
git receive-pack run on each end, transfers get full want/have negotiation
and server-built thin packs: fetching and pushing over iroh:// moves
exactly the same bytes as over ssh://, between any two machines that can
each reach the internet (or each other).
Prebuilt binary (Linux, Apple-silicon macOS; installs to ~/.local/bin):
curl -fsSL https://raw.githubusercontent.com/magik6k/git-remote-iroh/main/install.sh | sh
With cargo, from source (any platform, rust ≥ 1.91):
cargo install --git https://github.com/magik6k/git-remote-iroh
Or grab a binary from the releases page. However it gets there — once
git-remote-iroh is on PATH, git handles iroh:// URLs by itself.
git push iroh:// (with a bare URL) offers the repository for a single
fetch. It prints a URL, blocks until the other side has pulled, and then
reports the push as done:
# machine A
$ git push iroh:// main
# machine B — either of:
$ git clone iroh://endpoint…/8f00ba4… myrepo
$ git pull iroh://endpoint…/8f00ba4… main
Nothing is stored anywhere in between: the two machines talk directly (through an iroh relay only when hole-punching fails, still encrypted end to end).
# machine A
$ git-remote-iroh serve --writable
iroh://endpoint2rgc…/8f00ba4…
# machine B
$ git remote add laptop iroh://endpoint2rgc…/8f00ba4…
$ git fetch laptop
$ git push laptop main
The repository's identity lives in .git/iroh/, so the URL stays the same
across serve sessions — set it up as a named remote once and sync whenever
serve is running on the other side.
| Command | Description |
|---|---|
git-remote-iroh serve | Serve the current repository until Ctrl-C. |
serve --writable | Also accept pushes (git receive-pack). |
serve --once | Exit after the first successful session. |
serve --ephemeral | Throwaway identity; the URL only works for this session. |
git-remote-iroh id | Print the repo's stable short URL (dials via iroh discovery while serve runs). |
--writable). Share it like a password..git/iroh/. Delete that directory (or use --ephemeral) to rotate the
URL.git config receive.denyCurrentBranch updateInstead (serve prints a
hint). Pushing to other branches, or into a bare repo, just works.git push iroh:// reporting ok means one peer fetched the
offered refs — a way to hand a repo over, not durable storage.serve binds an iroh endpoint and prints iroh://<ticket>/<secret>. When
git sees an iroh:// URL it invokes this helper, which advertises the
connect capability, dials the ticket, authenticates with the secret, and
then simply shovels bytes between git and the git upload-pack /
git receive-pack spawned on the serving side. Offer mode
(git push iroh://) is sugar that serves the repository for exactly one
fetch. The stream-bridging approach follows n0's dumbpipe.
Licensed under the Apache License, Version 2.0.
Hacker News (1)
6 commits
Rust
90.9%
Shell
9.1%