Metadata-Version: 2.4
Name: rusty-git
Version: 0.2.1
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Version Control :: Git
Summary: High-speed pure Rust Git engine (gix + git2) for Python
Keywords: git,gix,pyo3,gitoxide,forge,libgit2
Author-email: Framework M <dev@framework-m.com>
License: Apache-2.0
Requires-Python: >=3.12
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://gitlab.com/framework-m/rusty-git
Project-URL: Issues, https://gitlab.com/framework-m/rusty-git/-/issues
Project-URL: Repository, https://gitlab.com/framework-m/rusty-git

# rusty-git

[![GitLab CI](https://gitlab.com/framework-m/rusty-git/badges/main/pipeline.svg)](https://gitlab.com/framework-m/rusty-git/-/pipelines)
[![PyPI version](https://img.shields.io/pypi/v/rusty-git.svg)](https://pypi.org/project/rusty-git/)
[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/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).

---

## Why rusty-git?

| Feature | `GitPython` | `pygit2` | `rusty-git` |
|---|---|---|---|
| **Execution Model** | Subprocess fork (`/usr/bin/git`) | C library bindings | **In-process pure Rust + PyO3** |
| **GIL Behavior** | Stalls Python thread during fork | Often holds GIL | **Releases GIL on both sync & async** |
| **Async / Tokio** | ❌ No | ❌ No | **✅ Native `asyncio.Future` via Tokio** |
| **Installation** | Pure Python (requires OS `git`) | Requires `libgit2.so` & C compiler | **Self-contained precompiled wheel** |
| **Smart-HTTP Wire Protocol** | ❌ No | ❌ Partial | **✅ In-process Smart-HTTP negotiation** |

---

## Installation

```bash
pip install rusty-git
# or with uv:
uv add rusty-git
```

---

## 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:

```python
import asyncio
import rusty_git


async def main():
    # 1. Initialize a bare repository
    repo_path = await rusty_git.init_bare_repository("/srv/repos/myorg/backend.git")

    # 2. Inspect commits
    commit = await rusty_git.get_commit(repo_path, "HEAD")
    print(commit["sha"], commit["message"], commit["author_name"])

    # 3. Read tree blobs without disk checkout
    readme = await rusty_git.get_tree_blob(repo_path, "main", "README.md")
    print(readme.decode("utf-8"))

    # 4. Fast unified diffs
    hunks = await rusty_git.compare_refs(repo_path, "main~1", "main")
    for hunk in hunks:
        print(hunk["new_path"], hunk["content"])

    # 5. 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`):

```python
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")

# 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",
)
```

---

## Smart-HTTP Protocol Wire Support

`rusty-git` can drive Git HTTP and SSH protocol negotiation completely in-process:

```python
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
```bash
cargo test
```

### Python Integration Tests
```bash
uv run pytest
```

---

## License

Apache-2.0 © Framework M Contributors

