rusty-git
High-speed pure Rust Git engine (gix + git2) compiled via PyO3 with both native async (Tokio) and GIL-released sync APIs.
rusty-git provides in-process Git operations with zero OS subprocess forks and statically-compiled native wheels (no dynamic libgit2.so dependencies required).
Installation
pip install rusty-git
# or with uv:
uv add rusty-git
Quickstart: 100% In-Process Demo (Zero Subprocesses)
Copy-paste this into example.py to test immediately in any environment:
import asyncio
import os
import tempfile
import rusty_git
async def main():
with tempfile.TemporaryDirectory() as tmp_dir:
repo_path = os.path.join(tmp_dir, "demo.git")
# 1. Initialize a bare repository in-process (ZERO subprocesses)
await rusty_git.init_bare_repository(repo_path)
# 2. Create the initial root commit in-process
res = await rusty_git.create_commit(
repo_path,
branch="main",
files={
"README.md": b"# Hello from rusty-git!\n",
"src/main.py": b"print('Hello World')\n",
},
message="Initial commit",
author_name="Alice",
author_email="alice@example.com",
)
print("Root Commit SHA:", res["commit_sha"])
# 3. Inspect commit in-process
commit = await rusty_git.get_commit(repo_path, "HEAD")
print(f"Author: {commit['author_name']} <{commit['author_email']}>")
print(f"Message: {commit['message']}")
# 4. Read tree blob without disk checkout
blob = await rusty_git.get_tree_blob(repo_path, "HEAD", "README.md")
print("Blob Content:", blob.decode("utf-8").strip())
# 5. List branches
branches = await rusty_git.list_branches(repo_path)
print("Branches:", branches)
asyncio.run(main())
Dual-Color Usage: Async & Sync
1. Asynchronous API (Default - for Litestar, FastAPI, Granian, Uvicorn)
All blocking Git I/O is offloaded to a Tokio multi-threaded worker pool, releasing the Python GIL:
import asyncio
import rusty_git
async def main():
repo_path = "/path/to/your/repo"
# 1. Inspect commits
commit = await rusty_git.get_commit(repo_path, "HEAD")
print(commit["sha"], commit["message"], commit["author_name"])
# 2. Read tree blobs without disk checkout
readme = await rusty_git.get_tree_blob(repo_path, "main", "README.md")
print(readme.decode("utf-8"))
# 3. Fast unified diffs
hunks = await rusty_git.compare_refs(repo_path, "main~1", "main")
for hunk in hunks:
print(hunk["new_path"], hunk["content"])
# 4. 3-Way Merge
result = await rusty_git.execute_merge(
repo_path,
base_ref="main",
head_ref="feature",
author_name="Automated Merge",
author_email="bot@example.com",
)
if result["status"] == "merged":
print("Merged Commit SHA:", result["commit_sha"])
asyncio.run(main())
2. Synchronous API (rusty_git.sync - for CLI tools, Celery, scripts)
Direct execution on the calling thread with the Python GIL cleanly released (py.detach):
import rusty_git
# Read commit synchronously
commit = rusty_git.sync.get_commit("/path/to/repo.git", "HEAD")
print(commit["sha"], commit["author_name"])
# List branches synchronously
branches = rusty_git.sync.list_branches("/path/to/repo.git")
print("Branches:", branches)
# Read file directly from commit tree
blob = rusty_git.sync.get_tree_blob("/path/to/repo.git", "HEAD", "pyproject.toml")
# Create a commit directly on any branch (new or existing)
res = rusty_git.sync.create_commit(
"/path/to/repo.git",
branch="feature-x",
files={"hello.txt": b"Hello world!\n"},
message="feat: add hello.txt",
)
# 3-Way Merge synchronously
result = rusty_git.sync.execute_merge(
"/path/to/repo.git",
"main",
"feature",
author_name="Merge Bot",
author_email="bot@example.com",
)
Architectural Note: Forges & Branch Management
rusty-git is designed for high-performance server-side forges and tools operating on bare repositories:
- Creating branches with commits: Passing any branch name to
create_commit(...)will create or advance that branch atomically. - Creating a branch without a commit: Git branches are simply ref pointers. To create a branch pointing to an existing commit without a new commit, your application or CLI can write the commit SHA directly to
refs/heads/<branch_name>. - Switching active branch (
HEAD): In a bare repo or CLI, switching the symbolic reference is done by writingref: refs/heads/<branch_name>\nto theHEADfile.
Engine Architecture: Pure gix vs. git2 Wire Streaming
rusty-git intentionally separates user-facing operations from network pack streaming:
- 100% Pure
gixCore (WebAssembly / Pyodide Ready):commit(atomic in-memory trees & commits),inspect(refs, tree blobs, histogram unified diffs), andmerge(3-way ORT tree merge) run entirely on pure-Rustgix. They require zero C headers and run in browsers and Pyodide. - Wire Protocol Pack Streaming (
git2): Ingesting thin packs (git push) and streaming sliding-window delta packs (git clone/git fetch) uselibgit2's battle-tested pack engine. Oncegix-packhigh-level streaming pack generation reaches full maturity, these remaining wire endpoints will transition togix, completing the journey to 100% pure Rust.
This keeps rusty-git focused entirely on performance-critical operations without unnecessary file-I/O wrapper overhead.
Smart-HTTP Protocol Wire Support
rusty-git can drive Git HTTP and SSH protocol negotiation completely in-process:
Note on Transport & Auth (SSH / TLS):
rusty-gitoperates directly on request/response byte streams rather than managing sockets. Transport encryption and authentication (SSH keys viaasyncssh/OpenSSH, or TLS/mTLS client certs via Nginx/Caddy/HTTPX) happen cleanly at the transport layer before passing payloads torusty-git.
import rusty_git
# Ref advertisement for git-upload-pack (git clone / fetch)
advert = await rusty_git.advertise("/srv/repos/myorg/backend.git", "git-upload-pack")
# Handle pack negotiation and streaming
upload_res = await rusty_git.upload_pack("/srv/repos/myorg/backend.git", request_body)
# Ingest inbound git push packfile atomically
push_res = await rusty_git.receive_pack("/srv/repos/myorg/backend.git", push_body)
print("Updated Refs:", push_res["updated_refs"])
Development & Testing
Rust Tests
cargo test
Python Integration Tests
uv run pytest
License
Apache-2.0 © Framework M Contributors
Metadata
Release files for rusty-git 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| rusty_git-0.3.0.tar.gz | 68.4 kB | Without provenance | Details for rusty_git-0.3.0.tar.gz |
Built distributions (wheels)
Total release size: 27.3 MB
Release files / rusty_git-0.3.0.tar.gz
| Download URL | rusty_git-0.3.0.tar.gz |
|---|---|
| Size | 68.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
eb47ed8c5ae81a7b2ca715687ca5f671f2274d5a5fa75f4b106b221f409b0aad
|
|
BLAKE2b-256 checksum How to use checksums |
866cc8b03527d698e53c719ee50a2d2be19910ea387c2c07eab3c4be659cf006
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.16
|
Release files / rusty_git-0.3.0-cp312-abi3-win_amd64.whl
| Download URL | rusty_git-0.3.0-cp312-abi3-win_amd64.whl |
|---|---|
| Size | 5.8 MB |
| Tags | CPython 3.12 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
c80a9c5bef424668c2dbddbb0494c56580fb5f0c086edae8afdcec60b994d2cc
|
|
BLAKE2b-256 checksum How to use checksums |
a202f1b526890788cab5ae8c7397f9b7ea43084b37f96d2ec0ed43ff53a707b7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.16
|
Release files / rusty_git-0.3.0-cp312-abi3-pyemscripten_2024_0_wasm32.whl
| Download URL | rusty_git-0.3.0-cp312-abi3-pyemscripten_2024_0_wasm32.whl |
|---|---|
| Size | 1.7 MB |
| Tags | CPython 3.12 PyEmscripten 2024.0+ WebAssembly abi3 |
|
SHA-256 checksum How to use checksums |
f8dce0dd04b02f66e8a6bf5febbd492239c08fe38f5a4b56a55f36a4fd76e537
|
|
BLAKE2b-256 checksum How to use checksums |
14de2e46d9d2b8ff3e6de313f71cd12a11b28b361eee3a862ad4c5c2458b08b6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.16
|
Release files / rusty_git-0.3.0-cp312-abi3-musllinux_1_2_x86_64.whl
| Download URL | rusty_git-0.3.0-cp312-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 3.4 MB |
| Tags | CPython 3.12 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
397fb95a726d00e17ef575d7b5fcb14e653abc422348a8d1c93252d17c1a1266
|
|
BLAKE2b-256 checksum How to use checksums |
73bf82319bbb0de7a83a566f4707fbcd7234b3af46646104089e323b2870af65
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.16
|
Release files / rusty_git-0.3.0-cp312-abi3-musllinux_1_2_aarch64.whl
| Download URL | rusty_git-0.3.0-cp312-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.12 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
dd82c07ec86c3c24d3bd62d0f3239c6fd36bfda4409257f9135096876422574c
|
|
BLAKE2b-256 checksum How to use checksums |
f425ee5ec011b64c0c56df73d56fb7a9ebcb41b28791010cb28aa85b7b7bfb21
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.16
|
Release files / rusty_git-0.3.0-cp312-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
| Download URL | rusty_git-0.3.0-cp312-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl |
|---|---|
| Size | 3.2 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
6207f10edad7205a458ea553073638b90881753b42cf67f03179640a335ee22e
|
|
BLAKE2b-256 checksum How to use checksums |
dda24c58295053b7b8b8603e6e87b5ad4ebc967e584a3801471459b9786bf717
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.16
|
Release files / rusty_git-0.3.0-cp312-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
| Download URL | rusty_git-0.3.0-cp312-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
0b2f4262135dc8beef1bb661c2fcbb0e40e375700baf1f9824cb92b496857be8
|
|
BLAKE2b-256 checksum How to use checksums |
9b1c672d65dab2fb3b3436df6cfc0bb922ea41dd469c5cb0201c7fdb1e2540ab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.16
|
Release files / rusty_git-0.3.0-cp312-abi3-macosx_11_0_arm64.whl
| Download URL | rusty_git-0.3.0-cp312-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 3.4 MB |
| Tags | CPython 3.12 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
d5648305917a55c9a176e370c657bb9ec685a55162f7805fb933018b5b55152f
|
|
BLAKE2b-256 checksum How to use checksums |
d3d7f4791a926bba9fc5848fc2ec0a60a82326e49a4ceb5316cce53d7d7460a8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.16
|
Release files / rusty_git-0.3.0-cp312-abi3-macosx_10_12_x86_64.whl
| Download URL | rusty_git-0.3.0-cp312-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 3.5 MB |
| Tags | CPython 3.12 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
8f13dfd41c9561b62ea2540d930d11ba681f7b81911883d4d141e272b8fdb7f9
|
|
BLAKE2b-256 checksum How to use checksums |
4dcd8044adf18495c65f16ccb41db7daff68c892b6493978e215dd29800dbce5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.16
|
Security for rusty-git 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.