Skip to content

Commit 926acaf

Browse files
committed
Add AGENTS.md file
Assisted-by: Kimi-k2.6
1 parent 2d9fc7d commit 926acaf

2 files changed

Lines changed: 190 additions & 0 deletions

File tree

‎AGENTS.md‎

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
# pygit2 Agent Guide
2+
3+
## Project Overview
4+
5+
**pygit2** is a Python library providing bindings to [libgit2](https://libgit2.org/), the shared C library that implements Git plumbing operations. It exposes both a low-level API (direct libgit2 wrappers) and a high-level Pythonic API for repository manipulation.
6+
7+
- **Version**: 1.19.2
8+
- **License**: GPLv2 with linking exception
9+
- **Maintainer**: J. David Ibáñez
10+
- **Python Support**: 3.11 – 3.14 and PyPy3 7.3+
11+
- **libgit2 Version**: 1.9.4
12+
- **Homepage**: <https://www.pygit2.org/>
13+
- **Repository**: <https://github.com/libgit2/pygit2>
14+
15+
## Architecture
16+
17+
The project uses a **hybrid C/Python** architecture with two compiled extension modules:
18+
19+
- **`src/`** — C11 source files that compile into the `_pygit2` C extension module. Each file generally maps to a libgit2 concept:
20+
- Core objects: `blob.c`, `commit.c`, `object.c`, `tag.c`, `tree.c`
21+
- Repository and refs: `repository.c`, `branch.c`, `reference.c`, `refdb.c`, `refdb_backend.c`, `revspec.c`
22+
- Diff and patch: `diff.c`, `patch.c`
23+
- ODB and backend: `odb.c`, `odb_backend.c`
24+
- Filters and mailmap: `filter.c`, `mailmap.c`
25+
- Notes and signatures: `note.c`, `signature.c`
26+
- Main module init: `pygit2.c`
27+
28+
- **`pygit2/`** — The main Python package.
29+
- **`_pygit2*.so`** — Compiled C extension (built from `src/`).
30+
- **`_libgit2.abi3.so`** — CFFI-generated ABI module built from `pygit2/_run.py`.
31+
- **`decl/`** — C header stub files used by CFFI to define the libgit2 API surface (e.g., `types.h`, `repository.h`, `callbacks.h`, `diff.h`, `remote.h`).
32+
- **`_build.py`** — Build-time helpers and the canonical `__version__` string. Also used at runtime to locate libgit2. Must remain importable without the rest of the package being built because `setup.py` imports it.
33+
- **`_run.py`** — CFFI build script that aggregates `decl/*.h` and compiles `pygit2._libgit2`.
34+
- **`ffi.py`** — Runtime import of the CFFI `ffi` and `lib` (`C`) objects.
35+
- **`_pygit2.pyi`** — Type stubs for the C extension. Keep it in sync when adding or changing low-level APIs.
36+
- **`py.typed`** — PEP 561 marker indicating the package is typed.
37+
- **High-level modules** — Pure-Python wrappers that sit on top of the C extension:
38+
`repository.py`, `callbacks.py`, `config.py`, `index.py`, `remotes.py`, `settings.py`, `submodules.py`, `transaction.py`, `filter.py`, `blob.py`, `blame.py`, `credentials.py`, `errors.py`, `options.py`, `packbuilder.py`, `references.py`, `refspec.py`, `utils.py`, `enums.py`, `legacyenums.py`.
39+
40+
- **`test/`** — pytest suite with fixture-based repository handling.
41+
- **`docs/`** — Sphinx documentation (RTD theme).
42+
43+
## Key Configuration Files
44+
45+
- **`setup.py`** — setuptools entry point. Builds both the C extension (`src/*.c`) and the CFFI extension (`pygit2/_run.py:ffi`).
46+
- **`pyproject.toml`** — Build system requirements, `cibuildwheel` configuration, `ruff` settings, and `codespell` settings.
47+
- **`setup.cfg`** — Legacy pycodestyle configuration.
48+
- **`pytest.ini`** — pytest configuration (`--capture=no -ra --verbose`, `testpaths = test/`).
49+
- **`mypy.ini`** — mypy configuration with strict settings.
50+
- **`mypy-stubtest.ini`** — mypy configuration for `stubtest` against `_pygit2.pyi`.
51+
- **`requirements.txt`** — Runtime/build requirements (`cffi>=2.0`, `setuptools` for Python >= 3.12).
52+
- **`requirements-test.txt`** — Test requirements (`pytest`, `pytest-cov`).
53+
- **`requirements-typing.txt`** — Typing requirements (`mypy`, `types-cffi`).
54+
- **`Makefile`** — Convenience targets: `make` builds deps + extension inplace; `make html` builds docs.
55+
56+
## Build and Test Commands
57+
58+
### Quick Development Build (inplace)
59+
60+
Requires libgit2 development headers and library to be installed on the system or pointed to via the `LIBGIT2` environment variable.
61+
62+
```bash
63+
python setup.py build_ext --inplace
64+
pytest
65+
```
66+
67+
### Full Build with Dependencies
68+
69+
The `build.sh` script can download, compile, and bundle libgit2 (and optionally libssh2 and OpenSSL) into a local prefix. On Windows, `build.ps1` handles libgit2 compilation via CMake.
70+
71+
```bash
72+
# Build inplace with bundled libgit2/libssh2/OpenSSL
73+
make
74+
75+
# Or manually:
76+
LIBSSH2_VERSION=1.11.1 LIBGIT2_VERSION=1.9.4 sh build.sh
77+
78+
# Build inplace + run tests
79+
sh build.sh test
80+
81+
# Build a wheel, install it, and run tests
82+
sh build.sh wheel
83+
84+
# Run tests with coverage
85+
sh build.sh test # (build.sh already adds --cov=pygit2)
86+
87+
# Run mypy type checking
88+
sh build.sh mypy
89+
90+
# Run stubtest against the .pyi file
91+
sh build.sh stubtest
92+
```
93+
94+
### Environment Variables
95+
96+
- `LIBGIT2` — Base path where libgit2 is installed (default: `/usr/local` or `%ProgramFiles%\libgit2` on Windows).
97+
- `LIBGIT2_LIB` — Override the library directory specifically.
98+
- `LIBGIT2_VERSION` — If set, `build.sh` downloads and builds this libgit2 version.
99+
- `LIBSSH2_VERSION` — If set, `build.sh` downloads and builds libssh2 with SSH support.
100+
- `OPENSSL_VERSION` — If set, `build.sh` downloads and builds OpenSSL (mainly used for macOS universal builds on CI).
101+
102+
### Documentation Build
103+
104+
```bash
105+
# Build the extension first, then docs
106+
make # builds deps + extension
107+
make -C docs html # requires sphinx-rtd-theme
108+
```
109+
110+
## Code Style Guidelines
111+
112+
### Python
113+
114+
- **Formatter / Linter**: [ruff](https://docs.astral.sh/ruff/)
115+
- Target Python: 3.11+
116+
- Quote style: single quotes
117+
- Selected rules: `E4`, `E7`, `E9`, `F`, `I`, `UP035`, `UP007`
118+
- **Type checker**: mypy (strict settings enabled; see `mypy.ini`)
119+
- All Python source files must include the standard GPLv2 copyright header.
120+
121+
### C
122+
123+
- Standard: C11
124+
- All C source files must include the standard GPLv2 copyright header.
125+
- The `.vimrc` at repo root configures ALE with `-std=c11 -Wall` and includes the Python headers and `/usr/local/include`.
126+
127+
### Docstrings
128+
129+
Use the following style (from `docs/development.rst`):
130+
131+
```python
132+
def f(a, b):
133+
"""
134+
The general description goes here.
135+
136+
Returns: bla bla.
137+
138+
Parameters:
139+
140+
a : <type>
141+
Bla bla.
142+
143+
b : <type>
144+
Bla bla.
145+
146+
Examples::
147+
148+
>>> f(...)
149+
"""
150+
```
151+
152+
## Testing Instructions
153+
154+
- **Runner**: pytest
155+
- **Configuration**: `pytest.ini`
156+
```ini
157+
[pytest]
158+
addopts = --capture=no -ra --verbose
159+
testpaths = test/
160+
```
161+
- **Fixtures**: Defined in `test/conftest.py`. They yield `pygit2.Repository` instances extracted from zipped sample repos in `test/data/` (e.g., `testrepo.zip`, `barerepo.zip`).
162+
- **Test utilities**: `test/utils.py` provides helpers such as `TemporaryRepository`, network/proxy/SSH skip markers, and `diff_safeiter`.
163+
- **Isolation**: The session-scoped `global_git_config` fixture clears `GLOBAL`, `XDG`, and `SYSTEM` config search paths to ensure reproducibility.
164+
- **Coverage**: `pytest-cov` is used; run via `sh build.sh test`.
165+
166+
## CI / Deployment
167+
168+
GitHub Actions workflows live in `.github/workflows/`:
169+
170+
- **`tests.yml`** — Runs on s390x via QEMU (allowed to fail; see issue #812).
171+
- **`lint.yml`** — Runs `ruff format --diff`, `ruff check`, and `sh build.sh mypy`.
172+
- **`wheels.yml`** — Uses `cibuildwheel` to build wheels for Linux (amd64, arm64, ppc64le, musl), macOS (intel, arm64, PyPy), and Windows (x64, x86, arm64). Publishes to PyPI and creates GitHub Releases on version tags (`v*`).
173+
- **`codespell.yml`** — Spell checking.
174+
175+
## Security Considerations
176+
177+
- The project links against OpenSSL and libssh2. CI pins specific versions of these libraries when building wheels.
178+
- Wheel repair commands (`auditwheel`, `delocate-wheel`) bundle shared libraries so wheels are self-contained.
179+
- Credentials callbacks (`RemoteCallbacks`, `get_credentials`) are the primary interface for supplying secrets; never hardcode credentials in tests.
180+
- Valgrind support: see `docs/development.rst` and `misc/valgrind-python.supp` for memory-leak debugging instructions.
181+
182+
## Useful Notes for Agents
183+
184+
- **Do not assume libgit2 is installed globally.** Check for `LIBGIT2` or use `build.sh`.
185+
- **`pygit2/_build.py`** is imported by `setup.py`; it must remain importable without the rest of the package being built.
186+
- **CFFI and setuptools extensions are both built from `setup.py`.** `ext_modules` builds the C extension from `src/*.c`; `cffi_modules` triggers the CFFI build via `pygit2/_run.py:ffi`.
187+
- **`.pyi` stub file**: `pygit2/_pygit2.pyi` provides type stubs for the C extension. Keep it in sync when adding or changing low-level APIs.
188+
- **`pygit2/__init__.py`** is large because it re-exports a vast surface of constants and classes. Follow existing patterns when adding new public symbols.

‎CHANGELOG.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
[#1458](https://github.com/libgit2/pygit2/issues/1458)
1919
[#1460](https://github.com/libgit2/pygit2/pull/1460)
2020

21+
- Add `AGENTS.md` file generated by Kimi-k2.6
22+
2123

2224
# 1.19.2 (2026-03-29)
2325

0 commit comments

Comments
 (0)