Peer-to-peer Git over Bluetooth. Push, pull, and clone repositories between nearby Macs without Wi-Fi, internet, or a server.
- Bluetooth L2CAP channels: uses CoreBluetooth's direct L2CAP sockets for high-throughput streaming (no BLE GATT overhead)
- Full Git protocol: reads and writes real Git packfiles via
git pack-objectsandgit index-pack; works with any existing repo - Push, pull, fetch and clone: bidirectional; fetch downloads commits into
refs/remotes/bltgit/without touching the working tree - Connection check: quickly verify Bluetooth reachability and trust setup with
bltgit ping <device> - Remote log: peek at the commit history on another Mac without downloading anything locally
- Remote status: compare local branches with a remote in seconds, with no data transferred
- Chunked, reliable transfer: 60 KB chunks with sequence numbers, ACKs, and retry logic survive transient BT glitches
- Transfer resume: if a connection drops mid-transfer, just retry the same command — it picks up from the last saved checkpoint (at most 8 chunks back)
- Mutual PIN pairing: first-time connections require both sides to confirm a 6-digit PIN; subsequent connections skip it via a local trust store
- Non-blocking async I/O: event-driven stream bridge with no polling loops; the CoreBluetooth RunLoop and async tasks never starve each other
- macOS 13.0 or later
- Swift 5.8 or later (
swift build) - Bluetooth hardware (built into every Mac)
giton both machines (used for packfile generation and application)
git clone <this-repo>
cd bltgit-v2
swift build -c release
# Binary is at .build/arm64-apple-macosx/release/bltgitTo install system-wide:
sudo cp .build/arm64-apple-macosx/debug/bltgit /usr/local/bin/bltgitFor a quick test without installing, you can also just run the debug build:
swift build
.build/arm64-apple-macosx/debug/bltgit --helpRun this in the directory you want to share:
bltgit serve
# Serving repo at /path/to/your/repo...The Mac will advertise itself over Bluetooth and wait for connections. It handles both incoming pull and push requests.
bltgit discover
# Found: <DEVICE_NAME> <UUID> RSSI: -52 dBmUse this when you want to confirm the remote is reachable and paired before running pull, push, or clone:
bltgit ping "<DEVICE_NAME>"
# Ping success: paired and connected to <DEVICE_NAME> (<UUID>)Device names are matched case-insensitively, and you can still pass the raw UUID from bltgit discover.
bltgit clone "<DEVICE_NAME>" ./my-project
# or use the UUID from discover:
bltgit clone <UUID> ./my-projectOn first connection you will be asked to confirm a PIN displayed on the other Mac. After pairing, subsequent connections are automatic.
# Inside an existing bltgit-cloned repo:
bltgit pull "<DEVICE_NAME>"Download new commits into refs/remotes/bltgit/ without touching your working tree:
bltgit fetch "<DEVICE_NAME>"
# Fetch complete.
# refs/remotes/bltgit/main
#
# To inspect: git log refs/remotes/bltgit/main
# To merge: git merge refs/remotes/bltgit/mainUseful when you want to review what changed before committing to a merge.
bltgit push "<DEVICE_NAME>"See the last 20 commits on another Mac without pulling anything:
bltgit log "<DEVICE_NAME>"
# Commit log for <DEVICE_NAME>:
# ------------------------------------------------------------
# abc1234 Jane Doe 3 hours ago Fix scanner timeout
# def5678 Bob Smith 1 day ago Add chunked transfer retry
# f1a2b3c Jane Doe 2 days ago Initial commitSee how your local branches compare to another Mac without transferring any data:
bltgit status "<DEVICE_NAME>"
# Status vs <DEVICE_NAME>:
# ------------------------------------------------------------
# develop 2 commits ahead
# feature diverged (1 ahead, 3 behind)
# main up to date
# old-exp local onlyClassifications: up to date, N commits ahead, N commits behind, diverged, remote only, local only, remote has new commits (run bltgit fetch).
See what would change if you pulled from a remote, without merging anything locally:
bltgit diff "<DEVICE_NAME>"
# Shows the diff between local HEAD and refs/remotes/bltgit/<branch>This is useful when you want to inspect incoming changes before deciding whether to fetch, merge, or pull.
bltgit devices
# Trusted devices:
# "<DEVICE_NAME>" (<UUID>) paired Jun 2, 2026- Discovery: the server publishes a BLE advertisement containing a CoreBluetooth L2CAP PSM (channel number) in a GATT characteristic.
- Connection: the client reads the PSM and opens a direct L2CAP socket, bypassing the GATT overhead for raw byte streaming.
- Pairing: both sides exchange a SHA-256 hash of a 6-digit PIN; the trust result is saved to
~/.config/bltgit/trusted_devices.json. - Transfer: Git packfiles are split into 60 KB chunks, each with a sequence number and ACK; the receiver reassembles and passes the result to
git index-pack. - Ref update: after a successful pack import, refs are updated with
git update-refand the working tree is checked out.
- Push always targets
refs/heads/main(current branch resolution not yet implemented) - Large repos (>100 MB pack) will be slower than Wi-Fi but work reliably
- macOS only; iOS does not support L2CAP server mode in CoreBluetooth
