You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**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.
5
+
**pygit2** is a Python library that provides bindings to
6
+
[libgit2](https://libgit2.org/), the shared C library that implements Git
7
+
plumbing operations. It exposes both a low-level API (direct libgit2 wrappers)
8
+
and a high-level, Pythonic API for repository manipulation.
6
9
7
-
-**Version**: 1.19.2
8
-
-**License**: GPLv2 with linking exception
10
+
-**Version**: 1.19.3 (canonical version is defined in `pygit2/_build.py`)
11
+
-**License**: GPLv2 with linking exception (see `COPYING`)
9
12
-**Maintainer**: J. David Ibáñez
10
13
-**Python Support**: 3.11 – 3.14 and PyPy3 7.3+
11
14
-**libgit2 Version**: 1.9.4
@@ -14,50 +17,78 @@
14
17
15
18
## Architecture
16
19
17
-
The project uses a **hybrid C/Python** architecture with two compiled extension modules:
20
+
The project uses a **hybrid C/Python** architecture with two compiled extension
21
+
modules:
18
22
19
-
-**`src/`** — C11 source files that compile into the `_pygit2` C extension module. Each file generally maps to a libgit2 concept:
23
+
-**`src/`** — C11 source and header files that compile into the `_pygit2` C
24
+
extension module. Each file generally maps to a libgit2 concept:
- Headers: `*.h` files mirroring the C sources (e.g. `repository.h`,
35
+
`diff.h`, `types.h`, `error.h`)
27
36
28
37
-**`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`.
38
+
-**`_pygit2*.so`** — Compiled C extension built from `src/`.
39
+
-**`_libgit2.abi3.so`** — CFFI-generated ABI module built from
40
+
`pygit2/_run.py`.
41
+
-**`decl/`** — C header stub files used by CFFI to define the libgit2 API
-**`.vimrc`** — Local editor configuration for C development with ALE
84
+
(`-std=c11 -Wall`, Python include path, `/usr/local/include`).
55
85
56
86
## Build and Test Commands
57
87
58
88
### Quick Development Build (inplace)
59
89
60
-
Requires libgit2 development headers and library to be installed on the system or pointed to via the `LIBGIT2` environment variable.
90
+
Requires libgit2 development headers and library to be installed on the system
91
+
or pointed to via the `LIBGIT2` environment variable.
61
92
62
93
```bash
63
94
python setup.py build_ext --inplace
@@ -66,7 +97,9 @@ pytest
66
97
67
98
### Full Build with Dependencies
68
99
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.
100
+
The `build.sh` script can download, compile, and bundle libgit2 (and optionally
101
+
libssh2, OpenSSL, and zlib) into a local prefix. On Windows, `build.ps1`
102
+
handles libgit2 compilation via CMake.
70
103
71
104
```bash
72
105
# Build inplace with bundled libgit2/libssh2/OpenSSL
@@ -75,14 +108,14 @@ make
75
108
# Or manually:
76
109
LIBSSH2_VERSION=1.11.1 LIBGIT2_VERSION=1.9.4 sh build.sh
77
110
78
-
# Build inplace + run tests
111
+
# Build inplace and run the tests
79
112
sh build.sh test
80
113
81
-
# Build a wheel, install it, and run tests
114
+
# Build a wheel, install it, and run the tests
82
115
sh build.sh wheel
83
116
84
117
# Run tests with coverage
85
-
sh build.sh test#(build.sh already adds --cov=pygit2)
118
+
sh build.sh test# build.sh adds --cov=pygit2
86
119
87
120
# Run mypy type checking
88
121
sh build.sh mypy
@@ -91,13 +124,32 @@ sh build.sh mypy
91
124
sh build.sh stubtest
92
125
```
93
126
127
+
`build.sh` creates a virtual environment under `ci/<python_tag>/` by default,
128
+
where `<python_tag>` is computed by `build_tag.py`. Use the `PYTHON`
129
+
environment variable to select a different interpreter (default: `python3`).
130
+
94
131
### Environment Variables
95
132
96
-
-`LIBGIT2` — Base path where libgit2 is installed (default: `/usr/local` or `%ProgramFiles%\libgit2` on Windows).
133
+
Variables consumed by `setup.py` / `pygit2/_build.py`:
134
+
135
+
-`LIBGIT2` — Base path where libgit2 is installed (default: `/usr/local` or
136
+
`%ProgramFiles%\libgit2` on Windows).
97
137
-`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).
138
+
139
+
Variables consumed by `build.sh`:
140
+
141
+
-`LIBGIT2_VERSION` — If set, download and build this libgit2 version.
142
+
-`LIBSSH2_VERSION` — If set, download and build libssh2 with SSH support.
143
+
-`OPENSSL_VERSION` — If set, download and build OpenSSL (mainly used for
144
+
macOS universal builds on CI).
145
+
-`ZLIB_VERSION` — If set, download and build zlib.
146
+
-`BUILD_TYPE` — CMake build type (default: `Debug`).
147
+
-`PYTHON` — Python interpreter to use (default: `python3`).
-**Type checker**: mypy (strict settings enabled; see `mypy.ini`)
119
171
- All Python source files must include the standard GPLv2 copyright header.
172
+
-`pygit2/__init__.py` is large because it re-exports a large surface of
173
+
constants and classes; follow existing patterns when adding new public
174
+
symbols.
120
175
121
176
### C
122
177
123
178
- Standard: C11
124
179
- 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`.
180
+
- The `.vimrc` at repo root configures ALE with `-std=c11 -Wall` and includes
181
+
the Python headers and `/usr/local/include`.
126
182
127
183
### Docstrings
128
184
@@ -158,31 +214,66 @@ def f(a, b):
158
214
addopts = --capture=no -ra --verbose
159
215
testpaths = test/
160
216
```
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.
217
+
-**Fixtures**: Defined in `test/conftest.py`. They yield `pygit2.Repository`
218
+
instances extracted from zipped sample repos in `test/data/` (e.g.
219
+
`testrepo.zip`, `barerepo.zip`). Named fixtures include `testrepo`,
-**Test utilities**: `test/utils.py` provides helpers such as
224
+
`TemporaryRepository`, `gen_blob_sha1`, `rmtree`, `diff_safeiter`, and
225
+
markers like `requires_network`, `requires_proxy`, `requires_ssh`,
226
+
`requires_refcount`, `fails_in_macos`, and `requires_future_libgit2`.
227
+
-**Isolation**: The session-scoped `global_git_config` fixture clears
228
+
`GLOBAL`, `XDG`, and `SYSTEM` config search paths to ensure reproducibility.
164
229
-**Coverage**: `pytest-cov` is used; run via `sh build.sh test`.
165
230
166
231
## CI / Deployment
167
232
168
233
GitHub Actions workflows live in `.github/workflows/`:
169
234
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.
235
+
-**`tests.yml`** — Runs on s390x via QEMU (`uraimo/run-on-arch-action`).
236
+
Allowed to fail; see issue #812.
237
+
-**`lint.yml`** — Runs `ruff format --diff`, `ruff check`, and
238
+
`sh build.sh mypy`.
239
+
-**`wheels.yml`** — Uses `cibuildwheel` to build wheels for Linux (amd64,
240
+
arm64, ppc64le, musl), macOS (intel, arm64, PyPy), and Windows (x64, x86,
241
+
arm64). It also builds an sdist, runs a `twine check`, publishes to PyPI,
242
+
and creates a GitHub Release on version tags (`v*`).
243
+
-**`codespell.yml`** — Spell checking with the codespell action.
244
+
245
+
The `cibuildwheel` configuration in `pyproject.toml` pins:
246
+
247
+
-`LIBGIT2_VERSION="1.9.4"`
248
+
-`LIBSSH2_VERSION="1.11.1"`
249
+
-`OPENSSL_VERSION="3.5.4"`
250
+
251
+
and skips `*musllinux_ppc64le` plus testing on `*-*linux_ppc64le` and
252
+
`pp*-macosx_arm64`.
174
253
175
254
## Security Considerations
176
255
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.
256
+
- The project links against OpenSSL and libssh2. CI pins specific versions of
- Credentials callbacks (`RemoteCallbacks`, `get_credentials`) are the primary
261
+
interface for supplying secrets; never hardcode credentials in tests.
262
+
- Valgrind support: see `docs/development.rst` and
263
+
`misc/valgrind-python.supp` for memory-leak debugging instructions.
181
264
182
265
## Useful Notes for Agents
183
266
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.
267
+
-**Do not assume libgit2 is installed globally.** Check for `LIBGIT2` or use
268
+
`build.sh` / `make`.
269
+
-**`pygit2/_build.py`** is imported by `setup.py`; it must remain importable
270
+
without the rest of the package being built.
271
+
-**CFFI and setuptools extensions are both built from `setup.py`.**
272
+
`ext_modules` builds the C extension from `src/*.c`; `cffi_modules` triggers
273
+
the CFFI build via `pygit2/_run.py:ffi`.
274
+
-**`.pyi` stub file**: `pygit2/_pygit2.pyi` provides type stubs for the C
275
+
extension. Keep it in sync when adding or changing low-level APIs.
276
+
-**Header stub order matters**: `pygit2/_run.py` concatenates `decl/*.h` in a
277
+
fixed list; add new stubs in the correct position if dependencies require it.
278
+
- Run the full test suite and type checks before considering a change complete:
0 commit comments