pail keeps your repository in S3 or GCS and lets every person and agent commit straight to it.
pail log, show and cat-file print exactly what Git would.pail hashes your changed files, uploads them next to a new commit object, and then does one conditional write to refs/main. That last write is the whole commit. If someone else got there first and touched different files, pail replays yours on top and tries again.
We ran the same edits through both CLIs from the same laptop. Each writer made 20 commits to one shared branch: git add/commit/push to a private GitHub repository, and pail add/commit to a GCS bucket. After each pail run we checked that every commit actually made it onto main.
| Writers on one branch | git → github.com | pail → GCS | Commits per second |
|---|---|---|---|
| 1 | 0.7 /s1.4 s per commit | 2.0 /s0.45 s per commit | |
| 4 | 0.65 /s | 2.1 /s | |
| 16 | 0.7 /s7.9 pushes per commit | 3.6 /snone lost |
A caveat: this was a home connection in Phoenix in October 2026, about 90 ms from github.com and 35 ms from storage.googleapis.com. Both tools spend most of their time waiting on round trips, so both get faster from a machine in the bucket's region. Calling pail as a library, without starting a process per commit, got to 7.1 commits per second with 16 writers.
pail land feature --stack puts every commit on a branch onto main in one write. If it fails partway, run it again. It picks up where it left off.
Working copies are copy-on-write clones of one shared cache. Build output gets cloned too, so a new worktree starts with a warm build and doesn't double your disk usage.
pail log, show, cat-file and ls-tree take Git's flags and print Git's output. We mirror our own monorepo into pail as it changes and check every commit byte for byte. Thousands of commits so far, no mismatches.
Nothing leaves your cloud account. People don't need bucket keys either: a credential provider hands out short-lived tokens that only work for one repository.
Changes to different files just work. When two writers change the same file, the second one gets exit code 4 and a list of the files, so a script or an agent knows exactly what to sync.
pre-commit, commit-msg and pre-publish all run before the branch moves. pre-publish sees the exact commit that's about to land.
A repository is a URL. Point it at whatever storage you already have, and install the credential provider that matches how your people sign in. Providers are small programs in their own GitHub repos, like gh extensions.
gs://bucket/repos3://bucket/repofile:///path/repohttps://host/repopail serve proxy, for people with no bucket access at allhttps://pail.archdev.ai/org/repopail auth install gcloudpail auth install gcs-downscopedpail auth install archdevpail auth install you/pail-credential-sso@v1.2.You don't need a server for pull requests or CI. The bucket already sends a notification whenever a branch moves. A CI runner listens for those, builds the exact commit, and saves its result as a commit on a _meta branch. Our pail-pr and pail-ci prototypes are short scripts that only call the pail CLI.
pail has no server of its own to break into. What's left is your bucket's permissions and the tokens people carry, so that's where the work goes.
refs/main, so a direct commit gets a 403 from Google. Or put pail serve in front and it checks every request.install.sh verifies the release checksum, and credential providers are installed from an exact commit with its sha256 recorded.How branch protection works
Building a token broker and a lander
Any S3 or GCS bucket works, or a local folder with file://.
curl -fsSL https://pail.build/install.sh | sh pail auth install gcloud pail init gs://acme-vcs/app pail clone gs://acme-vcs/app && cd app pail add -A pail commit -m "First commit" # published pail log --oneline