A git remote helper for Google Cloud Storage
Project description
git-remote-gcs
Use Google Cloud Storage as a Git remote. This is a GCP equivalent of awslabs/git-remote-s3.
It provides a git remote helper that lets you use a GCS bucket as a serverless Git server — no VMs, no Secure Source Manager, just a bucket.
Installation
pip install git-remote-gcs
Or install from source:
git clone <this-repo>
cd git-remote-gcs
pip install .
Prerequisites
- A GCP project with a GCS bucket (or create one):
gcloud storage buckets create gs://my-git-bucket --location=us-west1
-
Authentication configured — any of:
gcloud auth application-default login(local dev)- Service account key via
GOOGLE_APPLICATION_CREDENTIALS - Workload Identity (GKE)
- Attached service account (Compute Engine, Cloud Shell)
-
IAM permissions on the bucket. Minimum required:
storage.objects.createstorage.objects.getstorage.objects.deletestorage.objects.list
The simplest way is the Storage Object Admin role (
roles/storage.objectAdmin) on the bucket:
gcloud storage buckets add-iam-policy-binding gs://my-git-bucket \
--member="user:tyler@zerosumdefense.co" \
--role="roles/storage.objectAdmin"
For more granular per-repo access using prefixes, see Access Control.
Quick Start
Create a new repo
mkdir my-repo
cd my-repo
git init
git remote add origin gcs://my-git-bucket/my-repo
echo "Hello" > hello.txt
git add -A
git commit -m "initial commit"
git push --set-upstream origin main
Clone a repo
git clone gcs://my-git-bucket/my-repo my-repo-clone
Branches
cd my-repo
git checkout -b feature-branch
touch new_file.txt
git add -A
git commit -m "new feature"
git push origin feature-branch
Access Control
Access is controlled entirely through GCS IAM. You can scope permissions per-repo by using bucket prefixes and IAM conditions:
# Grant access to a specific repo prefix only
gcloud storage buckets add-iam-policy-binding gs://my-git-bucket \
--member="user:dev@example.com" \
--role="roles/storage.objectAdmin" \
--condition="expression=resource.name.startsWith('projects/_/buckets/my-git-bucket/objects/my-repo/'),title=my-repo-access"
Multiple repos can share the same bucket with different prefixes:
gcs://my-git-bucket/repo-a
gcs://my-git-bucket/repo-b
gcs://my-git-bucket/team/project-c
Data Encryption
GCS encrypts all data at rest by default with Google-managed keys. For additional control, use Customer-Managed Encryption Keys (CMEK):
gcloud storage buckets update gs://my-git-bucket \
--default-encryption-key=projects/PROJECT/locations/LOCATION/keyRings/RING/cryptoKeys/KEY
Concurrent Push Protection
git-remote-gcs uses GCS generation-match preconditions to implement per-reference locking, preventing concurrent pushes to the same branch.
If a lock acquisition fails:
error refs/heads/main "failed to acquire ref lock at my-repo/refs/heads/main/LOCK.lock.
Another client may be pushing. If this persists beyond 60s,
run git-gcs doctor gcs://my-git-bucket/my-repo --lock-ttl 60 to inspect and clear stale locks."
Configure the lock TTL via environment variable:
export GIT_REMOTE_GCS_LOCK_TTL=120 # seconds, default is 60
Managing the Remote
Doctor — diagnose and fix issues
git-gcs doctor gcs://my-git-bucket/my-repo
git-gcs doctor gcs://my-git-bucket/my-repo --delete-bundle # remove conflicting bundles
git-gcs doctor gcs://my-git-bucket/my-repo --lock-ttl 30 # clear locks older than 30s
Protect/unprotect branches
git-gcs protect gcs://my-git-bucket/my-repo main
git-gcs unprotect gcs://my-git-bucket/my-repo main
Protected branches cannot be force-pushed to or deleted.
Delete a remote branch
git-gcs delete-branch gcs://my-git-bucket/my-repo -b old-feature
Under the Hood
How it works
Bundles are stored in GCS as <prefix>/<ref>/<sha>.bundle.
Push:
- Acquire a per-ref lock using GCS generation-match preconditions
- Create a git bundle:
git bundle create <sha>.bundle <ref> - Upload the bundle to
<prefix>/<ref>/<sha>.bundle - Clean up the previous bundle for that ref
- Release the lock
Fetch:
- List all objects under
<prefix>/refs/to discover refs and SHAs - Download the bundle for each requested ref
- Unbundle locally with
git bundle unbundle
List:
- Scan
<prefix>/refs/for.bundleobjects - Extract ref names and SHAs from the object keys
- Read
<prefix>/HEADfor the default branch
Storage layout
gs://my-git-bucket/my-repo/
├── HEAD # default branch ref
├── refs/
│ ├── heads/
│ │ ├── main/
│ │ │ └── abc123...def.bundle # branch bundle
│ │ └── feature/
│ │ └── 789abc...012.bundle
│ └── tags/
│ └── v1.0/
│ └── 345def...678.bundle
Debugging
# Verbose output
GIT_REMOTE_GCS_VERBOSE=1 git push origin main
# Or use git's verbosity flag
git -c transfer.verbosity=2 push origin main
Comparison with Alternatives
| Feature | git-remote-gcs | Secure Source Manager | GitHub + Cloud Build | Gitea on VM |
|---|---|---|---|---|
| Cost | ~$0 (GCS storage) | $1,000/mo | Free (public) | Free tier VM |
| Managed | Yes (GCS) | Yes | Yes | No |
| IAM integration | Native GCP IAM | Native GCP IAM | Separate | None |
| Setup time | Minutes | Minutes | Minutes | 30+ min |
| UI / PRs | No | Yes | Yes | Yes |
| Serverless | Yes | Yes | N/A | No |
Inspired By
- awslabs/git-remote-s3 — the S3 equivalent this project is modeled after
- bgahagan/git-remote-s3 — the original S3 remote helper
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file git_remote_gcs-0.1.0.tar.gz.
File metadata
- Download URL: git_remote_gcs-0.1.0.tar.gz
- Upload date:
- Size: 13.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
128d8f1990211a0dce44881bd654224656e74537c93b66fa9861e3ee50068c34
|
|
| MD5 |
e183c83c6c430114bef67059289ad591
|
|
| BLAKE2b-256 |
a71567b2d8c3094e4b77b40fb05f4bd66e9e7657ec30cd17769ce02fc1312fd6
|
File details
Details for the file git_remote_gcs-0.1.0-py3-none-any.whl.
File metadata
- Download URL: git_remote_gcs-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1ed76936aef71844350edc69d86168ff514271849c49e5b86407344a2df98d6
|
|
| MD5 |
16a3953c7bbf96901aa54c41e1ba279c
|
|
| BLAKE2b-256 |
429b27f43f3f22f0b3dd882dd125f29a08ea56795670cb8f2c7bda92feaf596c
|