Metadata-Version: 2.4
Name: gitoxide-py
Version: 0.87.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Rust
Classifier: Topic :: Software Development :: Version Control :: Git
Classifier: Typing :: Typed
License-File: LICENSE
Summary: Typed Python bindings to the gix (gitoxide) engine that release the GIL for every call
Keywords: git,gitoxide,gix,vcs,version-control,pyo3
Author: Pol Feliu
License-Expression: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/feliupol/gitoxide-py
Project-URL: Repository, https://github.com/feliupol/gitoxide-py
Project-URL: gix (Rust crate), https://github.com/GitoxideLabs/gitoxide

# gitoxide-py

Python bindings to [gitoxide](https://github.com/GitoxideLabs/gitoxide) (the
`gix` Rust crate), built with [PyO3](https://pyo3.rs) and
[maturin](https://www.maturin.rs).

**Status: alpha, work in progress.**

Started from [shenxianpeng/gitoxide](https://github.com/shenxianpeng/gitoxide)
(MIT OR Apache-2.0) and reworked from there: every call releases the GIL, the
read surface covers diffs, reflogs, the index and submodules, and ref edits
are supported. Distributed as `gitoxide-py`, separately from that project's
`gitoxide` package.

## Design goals

- **API parity with `gix`.** Method and function names mirror `gix`'s own
  Rust API where a direct equivalent exists (`open`/`discover`/`init`,
  `git_dir`/`workdir`, `head_id`/`head_commit`, `rev_parse_single`,
  `rev_walk`/`commits`, ...), rather than mimicking GitPython's API shape.
- **The GIL is released for every call.** Every method wraps its gix work in
  `Python::detach`, so other Python threads keep running while a call is in
  flight. See the module doc comment in `src/lib.rs` for why `Repository` is
  backed by `gix::ThreadSafeRepository` rather than `gix::Repository` — the
  latter is never `Sync` (internal `RefCell`-based object cache), so it can't
  satisfy `detach`'s `Send` bound no matter how the pyclass is annotated.
- **Typed, with no hand-maintained stub file.** `pyo3`'s `experimental-inspect`
  feature embeds type introspection data into the built binary; `maturin
  build`/`develop --generate-stubs` extracts it and bundles the result into
  the wheel as a proper `gitoxide_py/` package (`__init__.py` + `.pyi` +
  `py.typed`, PEP 561), so `mypy`/`pyright` resolve real types against the
  installed package with no extra configuration — and the stub can never
  drift from the actual API, since it's generated from the same binary.
  Requires the declarative `#[pymodule] mod gitoxide_py { ... }` style in
  `src/lib.rs`; introspection doesn't support the older function-style
  `#[pymodule] fn gitoxide_py(m: &Bound<PyModule>) -> PyResult<()> { ... }`.

## Building

[uv](https://docs.astral.sh/uv/) manages the environment — `maturin` and
`pytest` are declared as a `dev` dependency group in `pyproject.toml`, locked
in `uv.lock`.

```bash
uv sync
uv run maturin develop --release --generate-stubs
```

## API

The generated stub (`gitoxide_py/__init__.pyi` in the installed package)
carries the full signature and doc of every function, method and attribute,
so editors and type checkers describe the API without a second copy of it
living here.

## Testing

```bash
uv run pytest -v
```

The tests build fixture repositories with the real `git` CLI and exercise the
API against them. `test_gil_release.py` is the exception: it asserts that
`Python::detach` actually lets another Python thread make progress during a
call, via the `_debug_detached_sleep` helper (not part of the public API).

CI (`.github/workflows/ci.yml`) runs on a self-hosted runner: `cargo fmt
--check`, `cargo clippy -D warnings`, `uv run maturin develop --release
--generate-stubs`, then `uv run pytest -v`.

## Scope

Alpha. Reading, plus the writes that are a ref edit and nothing more:
creating and deleting branches and tags, and setting local configuration.
Nothing here touches the working tree.

Covered: open/discover/init; HEAD and branch state; rev-parse and object
kinds; commit walks, in graph, date or topological order; merge-base,
ahead/behind and ancestry checks; tree entries and blob reads; tree-to-tree
diffs, with per-file line counts on request; remotes; linked worktrees;
submodules and their status; index entries and conflict stages; working-tree
status; reflogs; configuration reads and writes; and branch and tag creation
and deletion.

Not covered: anything over the network (`fetch`/`push`/`clone` need a
transport feature and a TLS backend, a dependency decision of its own), and
anything that writes commits, index entries or the working tree. Note that
those are also where `git` runs hooks — it runs none for a ref edit, and
neither does this.

## Layout

`src/lib.rs` assembles the Python module out of items defined beside it:
`src/repository.rs` holds the `Repository` handle and the functions that open
one, `src/types.rs` the value objects its methods return, and `src/util.rs`
the conversions they share.

