Skip to main content

rusty-git

GitLab CI PyPI version License: Apache 2.0

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 writing ref: refs/heads/<branch_name>\n to the HEAD file.

Engine Architecture: Pure gix vs. git2 Wire Streaming

rusty-git intentionally separates user-facing operations from network pack streaming:

  • 100% Pure gix Core (WebAssembly / Pyodide Ready): commit (atomic in-memory trees & commits), inspect (refs, tree blobs, histogram unified diffs), and merge (3-way ORT tree merge) run entirely on pure-Rust gix. 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) use libgit2's battle-tested pack engine. Once gix-pack high-level streaming pack generation reaches full maturity, these remaining wire endpoints will transition to gix, 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-git operates directly on request/response byte streams rather than managing sockets. Transport encryption and authentication (SSH keys via asyncssh/OpenSSH, or TLS/mTLS client certs via Nginx/Caddy/HTTPX) happen cleanly at the transport layer before passing payloads to rusty-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)

Source distribution for rusty-git 0.3.0
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)

Table of built distributions (wheels) for rusty-git 0.3.0
File Actions
rusty_git-0.3.0-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details for rusty_git-0.3.0-cp312-abi3-win_amd64.whl
rusty_git-0.3.0-cp312-abi3-pyemscripten_2024_0_wasm32.whl CPython 3.12 abi3 PyEmscripten 2024.0+ WebAssembly Details for rusty_git-0.3.0-cp312-abi3-pyemscripten_2024_0_wasm32.whl
rusty_git-0.3.0-cp312-abi3-musllinux_1_2_x86_64.whl CPython 3.12 abi3 Linux musl 1.2+ x86-64 Details for rusty_git-0.3.0-cp312-abi3-musllinux_1_2_x86_64.whl
rusty_git-0.3.0-cp312-abi3-musllinux_1_2_aarch64.whl CPython 3.12 abi3 Linux musl 1.2+ ARM64 Details for rusty_git-0.3.0-cp312-abi3-musllinux_1_2_aarch64.whl
rusty_git-0.3.0-cp312-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.12 abi3 Linux glibc 2.17+ x86-64 Details for rusty_git-0.3.0-cp312-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
rusty_git-0.3.0-cp312-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl CPython 3.12 abi3 Linux glibc 2.17+ ARM64 Details for rusty_git-0.3.0-cp312-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
rusty_git-0.3.0-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details for rusty_git-0.3.0-cp312-abi3-macosx_11_0_arm64.whl
rusty_git-0.3.0-cp312-abi3-macosx_10_12_x86_64.whl CPython 3.12 abi3 macOS 10.12+ x86-64 Details for rusty_git-0.3.0-cp312-abi3-macosx_10_12_x86_64.whl

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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page