Skip to content

ToonBettens/git-ferry

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 

Repository files navigation

git-ferry

git-ferry is a lightweight Git helper for exchanging commits over constrained or air‑gapped links using bundle cargo files.


How it works

  • One exchange branch per peer.
  • Exports create a single cargo file (.ferry) that contains:
    • a normal Git bundle (payload.bundle)
    • a small metadata file (ferry.meta)
  • Imports are fetch‑only into tracking refs (ferry-<peer>/<branch>). You decide when/how to merge.
  • Incremental export relies on ack to define the base commit.
  • Cargo files are just tar files and can be inspected.

Tracking refs are stored under:

ferry-<peer>/<branch>

Example: ferry-airlock/main

Inspect a cargo file manually:

tar -tf cargo.ferry
tar -xOf cargo.ferry ferry.meta

Installation

Put the script on your PATH, for example:

install -m 755 git-ferry ~/.local/bin/git-ferry

Commands

Setup

git ferry setup <peer> <branch>

Registers a peer and its exchange branch. Errors if the branch doesn’t exist locally.

Export

git ferry export <peer> <cargo.ferry>

Creates a single cargo file containing a bundle + metadata.

  • If no ack exists yet, exports a full bootstrap bundle.
  • If ack exists, exports only the range since that ack.

Import

git ferry import <peer> <cargo.ferry>

Fetches into:

ferry-<peer>/<branch>

No merge is done automatically.

Bootstrap

git ferry bootstrap <peer> <branch> <cargo.ferry>

Fetches into: Use this when the repo has no commits yet. It will:

  • configure the peer
  • import the cargo
  • create the branch from the imported history
ferry-<peer>/<branch>

No merge is done automatically.

Acknowledge

git ferry ack <peer>
git ferry ack <peer> <commit-ish>

Marks the last delivered commit for that peer. Call this on the sender side after you’ve confirmed the receiver applied the previous cargo. The next export becomes incremental after that commit.

Status

git ferry status [<peer>]

Shows configured branch, acked, last exported, and imported tip.

Forget

git ferry forget <peer>

Removes config and ferry refs/tracking refs.


Scenarios

1) First‑time exchange

Starting position: Two repos exist. No prior exchange. Goal: Send the full branch to the peer for the first time.

Sender (local):

git ferry setup airlock main
git ferry export airlock /tmp/cargo.ferry

<transfer cargo.ferry over the air‑gap>

Receiver (airlock):

git init
git ferry bootstrap local main /tmp/cargo.ferry

2) Incremental update after confirmation

Starting position: A previous cargo was imported successfully. Goal: Send only new commits since that confirmed delivery.

Sender (local):

# acknowledge the last successful delivery
git ferry ack airlock

# make new changes
echo "more" >> README.md
git commit -am "update readme"

# export only the new work
git ferry export airlock /tmp/cargo.ferry

<transfer cargo.ferry over the air‑gap>

Receiver (airlock):

git ferry import local /tmp/cargo.ferry
git merge --ff-only ferry-local/main

3) Airlock sends changes back

Starting position: Airlock has its own new commits. Goal: Send those commits back to local.

Sender (airlock):

echo "airlock edit" >> README.md
git commit -am "airlock edit"
git ferry export local /tmp/return.ferry

<transfer return.ferry over the air‑gap>

Receiver (local):

git ferry import airlock /tmp/return.ferry
git merge ferry-airlock/main

4) Re‑baseline after reset or lost state

Starting position: Peer config or state was lost, but you know a commit that both sides share. Goal: Resume incremental exports without a full bootstrap.

git ferry forget airlock
git ferry setup airlock main
git ferry ack airlock <commit-ish>

The next export will be incremental from that commit.

About

Exchanging commits over constrained or air-gapped links.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages