Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-pygit2 for openSUSE:Factory checked in at 2026-06-15 19:49:17 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pygit2 (Old) and /work/SRC/openSUSE:Factory/.python-pygit2.new.1981 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pygit2" Mon Jun 15 19:49:17 2026 rev:46 rq:1359492 version:1.19.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pygit2/python-pygit2.changes 2026-04-09 16:22:32.561078818 +0200 +++ /work/SRC/openSUSE:Factory/.python-pygit2.new.1981/python-pygit2.changes 2026-06-15 19:53:10.415897585 +0200 @@ -1,0 +2,8 @@ +Mon Jun 15 09:31:48 UTC 2026 - Daniel Garcia <[email protected]> + +- update to 1.19.3: + * Memory fixes #1368 #1417 #1443 + * Fix Repository.ident #1461 + * Documentation and annotation fixes #410 #1289 #1323 #1333 #1458 #1460 + +------------------------------------------------------------------- Old: ---- pygit2-1.19.2.tar.gz New: ---- pygit2-1.19.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pygit2.spec ++++++ --- /var/tmp/diff_new_pack.wKwYYA/_old 2026-06-15 19:53:11.063924763 +0200 +++ /var/tmp/diff_new_pack.wKwYYA/_new 2026-06-15 19:53:11.067924931 +0200 @@ -19,7 +19,7 @@ %{?sle15_python_module_pythons} Name: python-pygit2 -Version: 1.19.2 +Version: 1.19.3 Release: 0 Summary: Python bindings for libgit2 License: GPL-2.0-only ++++++ pygit2-1.19.2.tar.gz -> pygit2-1.19.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/AGENTS.md new/pygit2-1.19.3/AGENTS.md --- old/pygit2-1.19.2/AGENTS.md 1970-01-01 01:00:00.000000000 +0100 +++ new/pygit2-1.19.3/AGENTS.md 2026-06-13 09:30:16.557786700 +0200 @@ -0,0 +1,279 @@ +# pygit2 Agent Guide + +## Project Overview + +**pygit2** is a Python library that provides 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. + +- **Version**: 1.19.3 (canonical version is defined in `pygit2/_build.py`) +- **License**: GPLv2 with linking exception (see `COPYING`) +- **Maintainer**: J. David Ibáñez +- **Python Support**: 3.11 – 3.14 and PyPy3 7.3+ +- **libgit2 Version**: 1.9.4 +- **Homepage**: <https://www.pygit2.org/> +- **Repository**: <https://github.com/libgit2/pygit2> + +## Architecture + +The project uses a **hybrid C/Python** architecture with two compiled extension +modules: + +- **`src/`** — C11 source and header files that compile into the `_pygit2` C + extension module. Each file generally maps to a libgit2 concept: + - Core objects: `blob.c`, `commit.c`, `object.c`, `tag.c`, `tree.c` + - Repository, refs and branches: `repository.c`, `branch.c`, `reference.c`, + `refdb.c`, `refdb_backend.c`, `revspec.c`, `worktree.c` + - Diff and patch: `diff.c`, `patch.c` + - ODB and backends: `odb.c`, `odb_backend.c` + - Index, walking and helpers: `treebuilder.c`, `walker.c`, `oid.c`, + `note.c`, `signature.c`, `mailmap.c`, `stash.c` + - Filters: `filter.c` + - Module infrastructure: `pygit2.c`, `error.c`, `utils.c`, `wildmatch.c` + - Headers: `*.h` files mirroring the C sources (e.g. `repository.h`, + `diff.h`, `types.h`, `error.h`) + +- **`pygit2/`** — The main Python package. + - **`_pygit2*.so`** — Compiled C extension built from `src/`. + - **`_libgit2.abi3.so`** — CFFI-generated ABI module built from + `pygit2/_run.py`. + - **`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`). `pygit2/_run.py` concatenates these stubs in a specific order + before passing them to CFFI. + - **`_build.py`** — Build-time helpers and the canonical `__version__` + string. Also used at runtime to locate libgit2. It must remain importable + without the rest of the package being built because `setup.py` imports it. + - **`_run.py`** — CFFI build script that aggregates `decl/*.h` and compiles + `pygit2._libgit2`. + - **`ffi.py`** — Runtime import of the CFFI `ffi` and `lib` (`C`) objects. + - **`_pygit2.pyi`** — Type stubs for the C extension. Keep it in sync when + adding or changing low-level APIs. + - **`py.typed`** — PEP 561 marker indicating the package is typed. + - **High-level modules** — Pure-Python wrappers that sit on top of the C + extension: + `repository.py`, `callbacks.py`, `config.py`, `index.py`, `remotes.py`, + `settings.py`, `submodules.py`, `transaction.py`, `filter.py`, `blob.py`, + `blame.py`, `branches.py`, `credentials.py`, `errors.py`, `options.py`, + `packbuilder.py`, `references.py`, `refspec.py`, `utils.py`, `enums.py`, + `legacyenums.py`. + +- **`test/`** — pytest suite with fixture-based repository handling. +- **`docs/`** — Sphinx documentation (RTD theme). + +## Key Configuration Files + +- **`setup.py`** — setuptools entry point. Builds both the C extension + (`src/*.c`) and the CFFI extension (`pygit2/_run.py:ffi`). +- **`pyproject.toml`** — Build-system requirements, `cibuildwheel` + configuration, `ruff` settings, and `codespell` settings. +- **`setup.cfg`** — Legacy pycodestyle configuration. +- **`pytest.ini`** — pytest configuration (`--capture=no -ra --verbose`, + `testpaths = test/`). +- **`mypy.ini`** — mypy configuration with strict settings. +- **`mypy-stubtest.ini`** — mypy configuration for `stubtest` against + `_pygit2.pyi`. +- **`requirements.txt`** — Runtime/build requirements (`cffi>=2.0`, + `setuptools` for Python >= 3.12). +- **`requirements-test.txt`** — Test requirements (`pytest`, `pytest-cov`). +- **`requirements-typing.txt`** — Typing requirements (`mypy`, `types-cffi`). +- **`Makefile`** — Convenience targets: `make` builds dependencies + extension + inplace; `make html` builds docs. +- **`.vimrc`** — Local editor configuration for C development with ALE + (`-std=c11 -Wall`, Python include path, `/usr/local/include`). + +## Build and Test Commands + +### Quick Development Build (inplace) + +Requires libgit2 development headers and library to be installed on the system +or pointed to via the `LIBGIT2` environment variable. + +```bash +python setup.py build_ext --inplace +pytest +``` + +### Full Build with Dependencies + +The `build.sh` script can download, compile, and bundle libgit2 (and optionally +libssh2, OpenSSL, and zlib) into a local prefix. On Windows, `build.ps1` +handles libgit2 compilation via CMake. + +```bash +# Build inplace with bundled libgit2/libssh2/OpenSSL +make + +# Or manually: +LIBSSH2_VERSION=1.11.1 LIBGIT2_VERSION=1.9.4 sh build.sh + +# Build inplace and run the tests +sh build.sh test + +# Build a wheel, install it, and run the tests +sh build.sh wheel + +# Run tests with coverage +sh build.sh test # build.sh adds --cov=pygit2 + +# Run mypy type checking +sh build.sh mypy + +# Run stubtest against the .pyi file +sh build.sh stubtest +``` + +`build.sh` creates a virtual environment under `ci/<python_tag>/` by default, +where `<python_tag>` is computed by `build_tag.py`. Use the `PYTHON` +environment variable to select a different interpreter (default: `python3`). + +### Environment Variables + +Variables consumed by `setup.py` / `pygit2/_build.py`: + +- `LIBGIT2` — Base path where libgit2 is installed (default: `/usr/local` or + `%ProgramFiles%\libgit2` on Windows). +- `LIBGIT2_LIB` — Override the library directory specifically. + +Variables consumed by `build.sh`: + +- `LIBGIT2_VERSION` — If set, download and build this libgit2 version. +- `LIBSSH2_VERSION` — If set, download and build libssh2 with SSH support. +- `OPENSSL_VERSION` — If set, download and build OpenSSL (mainly used for + macOS universal builds on CI). +- `ZLIB_VERSION` — If set, download and build zlib. +- `BUILD_TYPE` — CMake build type (default: `Debug`). +- `PYTHON` — Python interpreter to use (default: `python3`). +- `PREFIX` — Installation prefix (default: `$(pwd)/ci/$PYTHON_TAG`). +- `CIBUILDWHEEL` — Set to `1` when invoked by cibuildwheel; changes package + manager and directory layout. +- `AUDITWHEEL_PLAT` — Linux platform for auditwheel repair. +- `LIBSSH2_OPENSSL` — Where to find OpenSSL when building libssh2. + +### Documentation Build + +```bash +# Build the extension first, then docs +make # builds deps + extension +make -C docs html # requires sphinx-rtd-theme +``` + +## Code Style Guidelines + +### Python + +- **Formatter / Linter**: [ruff](https://docs.astral.sh/ruff/) + - Target Python: 3.11+ + - Quote style: single quotes + - Selected rules: `E4`, `E7`, `E9`, `F`, `I`, `UP035`, `UP007` +- **Type checker**: mypy (strict settings enabled; see `mypy.ini`) +- All Python source files must include the standard GPLv2 copyright header. +- `pygit2/__init__.py` is large because it re-exports a large surface of + constants and classes; follow existing patterns when adding new public + symbols. + +### C + +- Standard: C11 +- All C source files must include the standard GPLv2 copyright header. +- The `.vimrc` at repo root configures ALE with `-std=c11 -Wall` and includes + the Python headers and `/usr/local/include`. + +### Docstrings + +Use the following style (from `docs/development.rst`): + +```python +def f(a, b): + """ + The general description goes here. + + Returns: bla bla. + + Parameters: + + a : <type> + Bla bla. + + b : <type> + Bla bla. + + Examples:: + + >>> f(...) + """ +``` + +## Testing Instructions + +- **Runner**: pytest +- **Configuration**: `pytest.ini` + ```ini + [pytest] + addopts = --capture=no -ra --verbose + testpaths = test/ + ``` +- **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`). Named fixtures include `testrepo`, + `testrepo_path`, `barerepo`, `barerepo_path`, `emptyrepo`, `dirtyrepo`, + `mergerepo`, `encodingrepo`, `testrepopacked`, `gpgsigned`, `blameflagsrepo`, + and `pygit2_empty_key`. +- **Test utilities**: `test/utils.py` provides helpers such as + `TemporaryRepository`, `gen_blob_sha1`, `rmtree`, `diff_safeiter`, and + markers like `requires_network`, `requires_proxy`, `requires_ssh`, + `requires_refcount`, `fails_in_macos`, and `requires_future_libgit2`. +- **Isolation**: The session-scoped `global_git_config` fixture clears + `GLOBAL`, `XDG`, and `SYSTEM` config search paths to ensure reproducibility. +- **Coverage**: `pytest-cov` is used; run via `sh build.sh test`. + +## CI / Deployment + +GitHub Actions workflows live in `.github/workflows/`: + +- **`tests.yml`** — Runs on s390x via QEMU (`uraimo/run-on-arch-action`). + Allowed to fail; see issue #812. +- **`lint.yml`** — Runs `ruff format --diff`, `ruff check`, and + `sh build.sh mypy`. +- **`wheels.yml`** — Uses `cibuildwheel` to build wheels for Linux (amd64, + arm64, ppc64le, musl), macOS (intel, arm64, PyPy), and Windows (x64, x86, + arm64). It also builds an sdist, runs a `twine check`, publishes to PyPI, + and creates a GitHub Release on version tags (`v*`). +- **`codespell.yml`** — Spell checking with the codespell action. + +The `cibuildwheel` configuration in `pyproject.toml` pins: + +- `LIBGIT2_VERSION="1.9.4"` +- `LIBSSH2_VERSION="1.11.1"` +- `OPENSSL_VERSION="3.5.4"` + +and skips `*musllinux_ppc64le` plus testing on `*-*linux_ppc64le` and +`pp*-macosx_arm64`. + +## Security Considerations + +- The project links against OpenSSL and libssh2. CI pins specific versions of + these libraries when building wheels. +- Wheel repair commands (`auditwheel`, `delocate-wheel`) bundle shared + libraries so wheels are self-contained. +- Credentials callbacks (`RemoteCallbacks`, `get_credentials`) are the primary + interface for supplying secrets; never hardcode credentials in tests. +- Valgrind support: see `docs/development.rst` and + `misc/valgrind-python.supp` for memory-leak debugging instructions. + +## Useful Notes for Agents + +- **Do not assume libgit2 is installed globally.** Check for `LIBGIT2` or use + `build.sh` / `make`. +- **`pygit2/_build.py`** is imported by `setup.py`; it must remain importable + without the rest of the package being built. +- **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`. +- **`.pyi` stub file**: `pygit2/_pygit2.pyi` provides type stubs for the C + extension. Keep it in sync when adding or changing low-level APIs. +- **Header stub order matters**: `pygit2/_run.py` concatenates `decl/*.h` in a + fixed list; add new stubs in the correct position if dependencies require it. +- Run the full test suite and type checks before considering a change complete: + `sh build.sh test` and `sh build.sh mypy`. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/AUTHORS.md new/pygit2-1.19.3/AUTHORS.md --- old/pygit2-1.19.2/AUTHORS.md 2026-03-29 15:47:01.114112000 +0200 +++ new/pygit2-1.19.3/AUTHORS.md 2026-06-13 09:30:16.557786700 +0200 @@ -74,6 +74,7 @@ Christian Häggström Edmundo Carmona Antoranz Erik Johnson + Ethan Meng Filip Rindler Fraser Tweedale Grégoire ROCHER @@ -206,6 +207,7 @@ Matěj Cepl Maxwell G Michał Górny + Mukunda Rao Katta Na'aman Hirschfeld Nicolas Rybowski Nicolás Sanguinetti diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/CHANGELOG.md new/pygit2-1.19.3/CHANGELOG.md --- old/pygit2-1.19.2/CHANGELOG.md 2026-03-29 15:47:01.114112000 +0200 +++ new/pygit2-1.19.3/CHANGELOG.md 2026-06-13 09:30:16.558183400 +0200 @@ -1,3 +1,28 @@ +# 1.19.3 (2026-06-13) + +- Memory fixes + [#1368](https://github.com/libgit2/pygit2/issues/1368) + [#1417](https://github.com/libgit2/pygit2/issues/1417) + [#1443](https://github.com/libgit2/pygit2/issues/1443) + +- Fix `Repository.ident` + [#1461](https://github.com/libgit2/pygit2/pull/1461) + +- Build/CI fixes and updates + [#1454](https://github.com/libgit2/pygit2/issues/1454) + [#1459](https://github.com/libgit2/pygit2/pull/1459) + +- Documentation and annotation fixes + [#410](https://github.com/libgit2/pygit2/issues/410) + [#1289](https://github.com/libgit2/pygit2/issues/1289) + [#1323](https://github.com/libgit2/pygit2/issues/1323) + [#1333](https://github.com/libgit2/pygit2/issues/1333) + [#1458](https://github.com/libgit2/pygit2/issues/1458) + [#1460](https://github.com/libgit2/pygit2/pull/1460) + +- Add `AGENTS.md` file generated by Kimi-k2.6 + + # 1.19.2 (2026-03-29) - Fix refcount and error handling issues in `filter_register(...)` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/CONTRIBUTING.md new/pygit2-1.19.3/CONTRIBUTING.md --- old/pygit2-1.19.2/CONTRIBUTING.md 1970-01-01 01:00:00.000000000 +0100 +++ new/pygit2-1.19.3/CONTRIBUTING.md 2026-06-13 09:30:16.558183400 +0200 @@ -0,0 +1,91 @@ +# Contributing to pygit2 + +Thank you for your interest in improving pygit2! This document covers how to submit pull requests and help others in the community. + +--- + +## Pull Requests + +We welcome pull requests that fix bugs, add features, improve documentation, or clean up code. To ensure a smooth review process, please follow the steps below. + +### Development Setup + +See the [install documentation](https://www.pygit2.org/install.html) for instructions on building pygit2 and its libgit2 dependency. + +### Making Changes + +1. **Fork the repository** and create a feature branch. +2. **Follow the existing code style** (see below). +3. **Add or update tests** for any new or changed behavior. Tests live in `test/` and are run with `pytest`. +4. **Update type stubs** (`pygit2/_pygit2.pyi`) if you modify the C extension's public API. +5. **Update `pygit2/__init__.py`** if you add new public symbols that should be re-exported. +6. **Ensure the test suite passes**: + ```bash + pytest + ``` +7. **Run the linters and type checker**: + ```bash + ruff format --diff + ruff check + sh build.sh mypy # or: mypy + sh build.sh stubtest # validate .pyi stubs + ``` +8. **Build the documentation** if you changed it (requires `sphinx-rtd-theme`): + ```bash + make -C docs html + ``` +9. **Write a clear commit message** explaining the *what* and *why*. + +### Code Style + +- **Python:** We target Python 3.11+. Use single quotes. Run `ruff format` and `ruff check` before submitting. +- **C:** We use C11. Follow `-std=c11 -Wall`. Match the style of the surrounding code in `src/`. +- **Copyright headers:** All source files must include the standard GPLv2 copyright header. Copy it from an existing file. +- **Docstrings:** Use the style shown in `docs/development.rst`: + ```python + def f(a, b): + """ + The general description goes here. + + Returns: bla bla. + + Parameters: + + a : <type> + Bla bla. + + b : <type> + Bla bla. + """ + ``` + +### Pull Request Review + +- All PRs require review from a maintainer. +- CI will run tests, linting, and type checks automatically. +- Be responsive to feedback and willing to iterate. +- Keep PRs focused. A pull request that does one thing well is easier to review than a large, mixed one. + +--- + +## Helping Others + +You do not need to write code to contribute. Helping others is valuable: + +- **Answer questions** in open issues and pull requests. If you know the answer, share it. +- **Review PRs.** Even if you are not a maintainer, constructive reviews from the community are welcome. +- **Improve documentation.** Doc fixes, clarifications, and typo corrections can be submitted as PRs just like code. +- **Reproduce reported issues.** Confirming a bug on your system helps maintainers prioritize fixes. + +--- + +## Commit Messages + +- Use the present tense and imperative mood (e.g., "Add support for…", not "Added support for…"). +- Keep the subject line under 72 characters. +- Reference related issues with `Fixes #123` or `Closes #456` when applicable. +- If you used AI assistance while preparing the change, mention it in the commit message with a tag such as `Assisted-by: Kimi-k2.6` (or the appropriate model name). + +--- + +Thank you for contributing! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/COPYING new/pygit2-1.19.3/COPYING --- old/pygit2-1.19.2/COPYING 2026-03-29 15:47:01.114112000 +0200 +++ new/pygit2-1.19.3/COPYING 2026-06-13 09:30:16.558183400 +0200 @@ -316,9 +316,8 @@ Copyright (C) <year> <name of author> This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/Makefile new/pygit2-1.19.3/Makefile --- old/pygit2-1.19.2/Makefile 2026-03-29 15:47:01.114112000 +0200 +++ new/pygit2-1.19.3/Makefile 2026-06-13 09:30:16.558183400 +0200 @@ -1,7 +1,7 @@ .PHONY: build html build: - OPENSSL_VERSION=3.5.4 LIBSSH2_VERSION=1.11.1 LIBGIT2_VERSION=1.9.2 sh build.sh + OPENSSL_VERSION=3.5.4 LIBSSH2_VERSION=1.11.1 LIBGIT2_VERSION=1.9.4 sh build.sh html: build make -C docs html diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/PKG-INFO new/pygit2-1.19.3/PKG-INFO --- old/pygit2-1.19.2/PKG-INFO 2026-03-29 15:47:05.747294000 +0200 +++ new/pygit2-1.19.3/PKG-INFO 2026-06-13 09:30:22.172716400 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: pygit2 -Version: 1.19.2 +Version: 1.19.3 Summary: Python bindings for libgit2. Home-page: https://github.com/libgit2/pygit2 Maintainer: J. David Ibáñez diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/build.ps1 new/pygit2-1.19.3/build.ps1 --- old/pygit2-1.19.2/build.ps1 2026-03-29 15:47:01.114112000 +0200 +++ new/pygit2-1.19.3/build.ps1 2026-06-13 09:30:16.558183400 +0200 @@ -1,3 +1,5 @@ +$ErrorActionPreference = 'Stop' + if (!(Test-Path -Path "build")) { # in case the pygit2 package build/ workspace has not been created by cibuildwheel yet mkdir build diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/build.sh new/pygit2-1.19.3/build.sh --- old/pygit2-1.19.2/build.sh 2026-03-29 15:47:01.114112000 +0200 +++ new/pygit2-1.19.3/build.sh 2026-06-13 09:30:16.558183400 +0200 @@ -22,14 +22,14 @@ # # sh build.sh # -# Build libgit2 1.9.2 (will use libssh2 if available), then build pygit2 +# Build libgit2 1.9.4 (will use libssh2 if available), then build pygit2 # inplace: # -# LIBGIT2_VERSION=1.9.2 sh build.sh +# LIBGIT2_VERSION=1.9.4 sh build.sh # -# Build libssh2 1.11.1 and libgit2 1.9.2, then build pygit2 inplace: +# Build libssh2 1.11.1 and libgit2 1.9.4, then build pygit2 inplace: # -# LIBSSH2_VERSION=1.11.1 LIBGIT2_VERSION=1.9.2 sh build.sh +# LIBSSH2_VERSION=1.11.1 LIBGIT2_VERSION=1.9.4 sh build.sh # # Build inplace and run the tests: # @@ -217,7 +217,7 @@ cp $OPENSSL_PREFIX/*.dylib $PREFIX/lib/ echo "PREFIX " $PREFIX echo "OPENSSL_PREFIX" $OPENSSL_PREFIX - ls -l /Users/runner/work/pygit2/pygit2/ci/ + ls -l $PREFIX ls -l $PREFIX/lib fi # we're done building dependencies, cibuildwheel action will take over diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/pygit2/_build.py new/pygit2-1.19.3/pygit2/_build.py --- old/pygit2-1.19.2/pygit2/_build.py 2026-03-29 15:47:01.116144400 +0200 +++ new/pygit2-1.19.3/pygit2/_build.py 2026-06-13 09:30:16.560943100 +0200 @@ -34,7 +34,7 @@ # # The version number of pygit2 # -__version__ = '1.19.2' +__version__ = '1.19.3' # diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/pygit2/_pygit2.pyi new/pygit2-1.19.3/pygit2/_pygit2.pyi --- old/pygit2-1.19.2/pygit2/_pygit2.pyi 2026-03-29 15:47:01.116144400 +0200 +++ new/pygit2-1.19.3/pygit2/_pygit2.pyi 2026-06-13 09:30:16.560943100 +0200 @@ -10,14 +10,16 @@ Type, TypedDict, TypeVar, + final, overload, ) +from typing_extensions import disjoint_base + from . import Index from ._libgit2.ffi import ( GitCommitC, GitObjectC, - GitProxyOptionsC, GitSignatureC, _Pointer, ) @@ -41,11 +43,6 @@ ) from .filter import Filter -GIT_OBJ_BLOB = Literal[3] -GIT_OBJ_COMMIT = Literal[1] -GIT_OBJ_TAG = Literal[4] -GIT_OBJ_TREE = Literal[2] - LIBGIT2_VER_MAJOR: int LIBGIT2_VER_MINOR: int LIBGIT2_VER_REVISION: int @@ -259,50 +256,50 @@ GIT_FILTER_ATTRIBUTES_FROM_HEAD: int GIT_FILTER_ATTRIBUTES_FROM_COMMIT: int -T = TypeVar('T') +_T = TypeVar('_T') -class _ObjectBase(Generic[T]): - _pointer: _Pointer[T] +class _ObjectBase(Generic[_T]): + _pointer: _Pointer[_T] filemode: FileMode id: Oid name: str | None raw_name: bytes | None short_id: str - type: 'Literal[GIT_OBJ_COMMIT] | Literal[GIT_OBJ_TREE] | Literal[GIT_OBJ_TAG] | Literal[GIT_OBJ_BLOB]' + type: 'Literal[ObjectType.COMMIT] | Literal[ObjectType.TREE] | Literal[ObjectType.TAG] | Literal[ObjectType.BLOB]' type_str: "Literal['commit'] | Literal['tree'] | Literal['tag'] | Literal['blob']" author: Signature committer: Signature tree: Tree @overload def peel( - self, target_type: 'Literal[GIT_OBJ_COMMIT, ObjectType.COMMIT] | Type[Commit]' + self, target_type: 'Literal[ObjectType.COMMIT] | Type[Commit]', / ) -> 'Commit': ... @overload def peel( - self, target_type: 'Literal[GIT_OBJ_TREE, ObjectType.TREE] | Type[Tree]' + self, target_type: 'Literal[ObjectType.TREE] | Type[Tree]', / ) -> 'Tree': ... @overload - def peel( - self, target_type: 'Literal[GIT_OBJ_TAG, ObjectType.TAG] | Type[Tag]' - ) -> 'Tag': ... + def peel(self, target_type: 'Literal[ObjectType.TAG] | Type[Tag]', /) -> 'Tag': ... @overload def peel( - self, target_type: 'Literal[GIT_OBJ_BLOB, ObjectType.BLOB] | Type[Blob]' + self, target_type: 'Literal[ObjectType.BLOB] | Type[Blob]', / ) -> 'Blob': ... @overload - def peel(self, target_type: 'None') -> 'Commit|Tree|Tag|Blob': ... + def peel(self, target_type: 'None', /) -> 'Commit|Tree|Tag|Blob': ... def read_raw(self) -> bytes: ... - def __eq__(self, other) -> bool: ... - def __ge__(self, other) -> bool: ... - def __gt__(self, other) -> bool: ... + def __eq__(self, other, /) -> bool: ... + def __ge__(self, other, /) -> bool: ... + def __gt__(self, other, /) -> bool: ... def __hash__(self) -> int: ... - def __le__(self, other) -> bool: ... - def __lt__(self, other) -> bool: ... - def __ne__(self, other) -> bool: ... + def __le__(self, other, /) -> bool: ... + def __lt__(self, other, /) -> bool: ... + def __ne__(self, other, /) -> bool: ... +@disjoint_base class Object(_ObjectBase[GitObjectC]): pass +@final class Reference: name: str raw_name: bytes @@ -315,27 +312,28 @@ def delete(self) -> None: ... def log(self) -> Iterator[RefLogEntry]: ... @overload - def peel(self, type: 'Literal[GIT_OBJ_COMMIT] | Type[Commit]') -> 'Commit': ... + def peel(self, type: 'Literal[ObjectType.COMMIT] | Type[Commit]') -> 'Commit': ... @overload - def peel(self, type: 'Literal[GIT_OBJ_TREE] | Type[Tree]') -> 'Tree': ... + def peel(self, type: 'Literal[ObjectType.TREE] | Type[Tree]') -> 'Tree': ... @overload - def peel(self, type: 'Literal[GIT_OBJ_TAG] | Type[Tag]') -> 'Tag': ... + def peel(self, type: 'Literal[ObjectType.TAG] | Type[Tag]') -> 'Tag': ... @overload - def peel(self, type: 'Literal[GIT_OBJ_BLOB] | Type[Blob]') -> 'Blob': ... + def peel(self, type: 'Literal[ObjectType.BLOB] | Type[Blob]') -> 'Blob': ... @overload def peel(self, type: 'None' = None) -> 'Commit|Tree|Tag|Blob': ... - def rename(self, new_name: str) -> None: ... + def rename(self, new_name: str, /) -> None: ... def resolve(self) -> Reference: ... def set_target(self, target: _OidArg, message: str = ...) -> None: ... - def __eq__(self, other) -> bool: ... - def __ge__(self, other) -> bool: ... - def __gt__(self, other) -> bool: ... - def __le__(self, other) -> bool: ... - def __lt__(self, other) -> bool: ... - def __ne__(self, other) -> bool: ... + def __eq__(self, other, /) -> bool: ... + def __ge__(self, other, /) -> bool: ... + def __gt__(self, other, /) -> bool: ... + def __le__(self, other, /) -> bool: ... + def __lt__(self, other, /) -> bool: ... + def __ne__(self, other, /) -> bool: ... class AlreadyExistsError(ValueError): ... +@final class Blob(Object): data: bytes is_binary: bool @@ -364,10 +362,10 @@ flags: BlobFilter = BlobFilter.CHECK_FOR_BINARY, commit_id: Optional[Oid] = None, ) -> None: ... - def __buffer__(self, flags: int) -> memoryview: ... - def __release_buffer__(self, buffer: memoryview) -> None: ... + def __buffer__(self, flags: int, /) -> memoryview: ... -class Branch(Reference): +@final +class Branch(Reference): # type: ignore[misc] branch_name: str raw_branch_name: bytes remote_name: str @@ -378,24 +376,7 @@ def is_head(self) -> bool: ... def rename(self, name: str, force: bool = False) -> 'Branch': ... # type: ignore[override] -class FetchOptions: - # incomplete - depth: int - proxy_opts: GitProxyOptionsC - -class CloneOptions: - # incomplete - version: int - checkout_opts: object - fetch_opts: FetchOptions - bare: int - local: object - checkout_branch: object - repository_cb: object - repository_cb_payload: object - remote_cb: object - remote_cb_payload: object - +@final class Commit(_ObjectBase[GitCommitC]): _pointer: _Pointer[GitCommitC] author: Signature @@ -412,6 +393,7 @@ tree: Tree tree_id: Oid +@disjoint_base class Diff: deltas: Iterator[DiffDelta] patch: str | None @@ -431,11 +413,12 @@ @staticmethod def from_c(diff, repo) -> Diff: ... @staticmethod - def parse_diff(git_diff: str | bytes) -> Diff: ... - def __getitem__(self, index: int) -> Patch | None: ... # Diff_getitem + def parse_diff(git_diff: str | bytes, /) -> Diff: ... + def __getitem__(self, index: int, /) -> Patch | None: ... # Diff_getitem def __iter__(self) -> Iterator[Patch | None]: ... # -> DiffIter def __len__(self) -> int: ... +@final class DiffDelta: flags: DiffFlag is_binary: bool @@ -446,6 +429,7 @@ status: DeltaStatus def status_char(self) -> str: ... +@final class DiffFile: flags: DiffFlag id: Oid @@ -454,8 +438,9 @@ raw_path: bytes size: int @staticmethod - def from_c(bytes) -> DiffFile: ... + def from_c(bytes, /) -> DiffFile: ... +@disjoint_base class DiffHunk: header: str lines: list[DiffLine] @@ -464,6 +449,7 @@ old_lines: int old_start: int +@final class DiffLine: content: str content_offset: int @@ -473,20 +459,26 @@ origin: str raw_content: bytes +@disjoint_base class DiffStats: deletions: int files_changed: int insertions: int def format(self, format: DiffStatsFormat, width: int) -> str: ... +@final class FilterSource: - # probably incomplete repo: object - pass + path: str + filemode: int + oid: Oid | None + mode: int + flags: int class GitError(Exception): ... class InvalidSpecError(ValueError): ... +@final class Mailmap: def __init__(self, *args) -> None: ... def add_entry( @@ -503,6 +495,7 @@ def resolve(self, name: str, email: str) -> tuple[str, str]: ... def resolve_signature(self, sig: Signature) -> Signature: ... +@final class Note: annotated_id: Oid id: Oid @@ -512,46 +505,52 @@ self, author: Signature, committer: Signature, ref: str = 'refs/notes/commits' ) -> None: ... +@final class Odb: backends: Iterator[OdbBackend] def __init__(self, *args, **kwargs) -> None: ... def add_backend(self, backend: OdbBackend, priority: int) -> None: ... - def add_disk_alternate(self, path: str | Path) -> None: ... - def exists(self, oid: _OidArg) -> bool: ... - def read(self, oid: _OidArg) -> tuple[ObjectType, bytes]: ... - def read_header(self, oid: _OidArg) -> tuple[ObjectType, int]: ... + def add_disk_alternate(self, path: str | Path, /) -> None: ... + def exists(self, oid: _OidArg, /) -> bool: ... + def read(self, oid: _OidArg, /) -> tuple[ObjectType, bytes]: ... + def read_header(self, oid: _OidArg, /) -> tuple[ObjectType, int]: ... def write(self, type: int, data: bytes | str) -> Oid: ... - def __contains__(self, other: _OidArg) -> bool: ... + def __contains__(self, other: _OidArg, /) -> bool: ... def __iter__(self) -> Iterator[Oid]: ... # Odb_as_iter +@disjoint_base class OdbBackend: def __init__(self, *args, **kwargs) -> None: ... - def exists(self, oid: _OidArg) -> bool: ... - def exists_prefix(self, partial_id: _OidArg) -> Oid: ... - def read(self, oid: _OidArg) -> tuple[int, bytes]: ... - def read_header(self, oid: _OidArg) -> tuple[int, int]: ... - def read_prefix(self, oid: _OidArg) -> tuple[int, bytes, Oid]: ... + def exists(self, oid: _OidArg, /) -> bool: ... + def exists_prefix(self, partial_id: _OidArg, /) -> Oid: ... + def read(self, oid: _OidArg, /) -> tuple[int, bytes]: ... + def read_header(self, oid: _OidArg, /) -> tuple[int, int]: ... + def read_prefix(self, oid: _OidArg, /) -> tuple[int, bytes, Oid]: ... def refresh(self) -> None: ... def __iter__(self) -> Iterator[Oid]: ... # OdbBackend_as_iter +@final class OdbBackendLoose(OdbBackend): def __init__(self, *args, **kwargs) -> None: ... +@final class OdbBackendPack(OdbBackend): def __init__(self, *args, **kwargs) -> None: ... +@final class Oid: raw: bytes def __init__(self, raw: bytes = ..., hex: str = ...) -> None: ... - def __eq__(self, other) -> bool: ... - def __ge__(self, other) -> bool: ... - def __gt__(self, other) -> bool: ... + def __eq__(self, other, /) -> bool: ... + def __ge__(self, other, /) -> bool: ... + def __gt__(self, other, /) -> bool: ... def __hash__(self) -> int: ... - def __le__(self, other) -> bool: ... - def __lt__(self, other) -> bool: ... - def __ne__(self, other) -> bool: ... + def __le__(self, other, /) -> bool: ... + def __lt__(self, other, /) -> bool: ... + def __ne__(self, other, /) -> bool: ... def __bool__(self) -> bool: ... +@final class Patch: data: bytes delta: DiffDelta @@ -570,6 +569,7 @@ interhunk_lines: int = 0, ) -> Patch: ... +@final class RefLogEntry: committer: Signature message: str @@ -577,25 +577,27 @@ oid_old: Oid def __init__(self, *args, **kwargs) -> None: ... +@final class Refdb: - def __init__(self, *args, **kwargs) -> None: ... + def __init__(self) -> None: ... def compress(self) -> None: ... @staticmethod - def new(repo: Repository) -> Refdb: ... + def new(repo: Repository, /) -> Refdb: ... @staticmethod - def open(repo: Repository) -> Refdb: ... - def set_backend(self, backend: RefdbBackend) -> None: ... + def open(repo: Repository, /) -> Refdb: ... + def set_backend(self, backend: RefdbBackend, /) -> None: ... +@disjoint_base class RefdbBackend: def __init__(self, *args, **kwargs) -> None: ... def compress(self) -> None: ... def delete( self, ref_name: str, old_id: _OidArg, old_target: str | None ) -> None: ... - def ensure_log(self, ref_name: str) -> bool: ... - def exists(self, refname: str) -> bool: ... - def has_log(self, ref_name: str) -> bool: ... - def lookup(self, refname: str) -> Reference: ... + def ensure_log(self, ref_name: str, /) -> bool: ... + def exists(self, refname: str, /) -> bool: ... + def has_log(self, ref_name: str, /) -> bool: ... + def lookup(self, refname: str, /) -> Reference: ... def rename( self, old_name: str, new_name: str, force: bool, who: Signature, message: str ) -> Reference: ... @@ -608,8 +610,8 @@ old: None | _OidArg, old_target: None | str, ) -> None: ... - def __iter__(self) -> Iterator[Reference]: ... +@final class RefdbFsBackend(RefdbBackend): def __init__(self, *args, **kwargs) -> None: ... @@ -619,15 +621,6 @@ # incomplete count: int -class PushOptions: - version: int - pb_parallelism: int - callbacks: object # TODO - proxy_opts: GitProxyOptionsC - follow_redirects: object # TODO - custom_headers: _StrArray - remote_push_options: _StrArray - class _LsRemotesDict(TypedDict): local: bool loid: Oid | None @@ -635,9 +628,22 @@ symref_target: str | None oid: Oid +@disjoint_base class Repository: def TreeBuilder(self, src: Tree | _OidArg = ...) -> TreeBuilder: ... - def _disown(self, *args, **kwargs) -> None: ... + def __init__(self, /, *args, **kwargs) -> None: ... + def _disown(self) -> None: ... + default_signature: Signature + head: Reference + head_is_detached: bool + head_is_unborn: bool + is_bare: bool + is_empty: bool + is_shallow: bool + odb: Odb + path: str | None + refdb: Refdb + workdir: str | None def add_worktree( self, name: str, path: str | Path, ref: Reference = ... ) -> Worktree: ... @@ -650,12 +656,12 @@ def apply( self, diff: Diff, location: ApplyLocation = ApplyLocation.WORKDIR ) -> None: ... - def cherrypick(self, id: _OidArg) -> None: ... + def cherrypick(self, id: _OidArg, /) -> None: ... def compress_references(self) -> None: ... def create_blob(self, data: str | bytes) -> Oid: ... - def create_blob_fromdisk(self, path: str) -> Oid: ... - def create_blob_fromiobase(self, iobase: IOBase) -> Oid: ... - def create_blob_fromworkdir(self, path: str | Path) -> Oid: ... + def create_blob_fromdisk(self, path: str, /) -> Oid: ... + def create_blob_fromiobase(self, iobase: IOBase, /) -> Oid: ... + def create_blob_fromworkdir(self, path: str | Path, /) -> Oid: ... def create_branch(self, name: str, commit: Commit, force=False) -> Branch: ... def create_commit( self, @@ -698,9 +704,9 @@ self, name: str, oid: _OidArg, type: ObjectType, tagger: Signature, message: str ) -> Oid: ... def descendant_of(self, oid1: _OidArg, oid2: _OidArg) -> bool: ... - def expand_id(self, hex: str) -> Oid: ... + def expand_id(self, hex: str, /) -> Oid: ... def free(self) -> None: ... - def git_object_lookup_prefix(self, oid: _OidArg) -> Object: ... + def git_object_lookup_prefix(self, oid: _OidArg, /) -> Object: ... def list_worktrees(self) -> list[str]: ... def listall_branches(self, flag: BranchType = BranchType.LOCAL) -> list[str]: ... def listall_mergeheads(self) -> list[Oid]: ... @@ -712,8 +718,8 @@ def lookup_note( self, annotated_id: str, ref: str = 'refs/notes/commits' ) -> Note: ... - def lookup_reference(self, name: str) -> Reference: ... - def lookup_reference_dwim(self, name: str) -> Reference: ... + def lookup_reference(self, name: str, /) -> Reference: ... + def lookup_reference_dwim(self, name: str, /) -> Reference: ... def lookup_worktree(self, name: str) -> Worktree: ... def merge_analysis( self, their_head: _OidArg, our_ref: str = 'HEAD' @@ -730,28 +736,30 @@ def references_iterator_init(self) -> Iterator[Reference]: ... def references_iterator_next( self, - iter: Iterator[T], + iter: Iterator[_T], references_return_type: ReferenceFilter = ReferenceFilter.ALL, ) -> Reference: ... def reset(self, oid: _OidArg, reset_type: ResetMode) -> None: ... - def revparse(self, revspec: str) -> RevSpec: ... - def revparse_ext(self, revision: str) -> tuple[Object, Reference]: ... - def revparse_single(self, revision: str) -> Object: ... - def set_odb(self, odb: Odb) -> None: ... - def set_refdb(self, refdb: Refdb) -> None: ... + def revparse(self, revspec: str, /) -> RevSpec: ... + def revparse_ext(self, revision: str, /) -> tuple[Object, Reference]: ... + def revparse_single(self, revision: str, /) -> Object: ... + def set_odb(self, odb: Odb, /) -> None: ... + def set_refdb(self, refdb: Refdb, /) -> None: ... def status( self, untracked_files: str = 'all', ignored: bool = False ) -> dict[str, int]: ... - def status_file(self, path: str) -> int: ... + def status_file(self, path: str, /) -> int: ... def walk( self, oid: _OidArg | None, sort_mode: SortMode = SortMode.NONE ) -> Walker: ... +@disjoint_base class RevSpec: flags: int from_object: Object to_object: Object +@final class Signature: _encoding: str | None _pointer: _Pointer[GitSignatureC] @@ -769,24 +777,26 @@ offset: int = 0, encoding: Optional[str] = None, ) -> None: ... - def __eq__(self, other) -> bool: ... - def __ge__(self, other) -> bool: ... - def __gt__(self, other) -> bool: ... - def __le__(self, other) -> bool: ... - def __lt__(self, other) -> bool: ... - def __ne__(self, other) -> bool: ... + def __eq__(self, other, /) -> bool: ... + def __ge__(self, other, /) -> bool: ... + def __gt__(self, other, /) -> bool: ... + def __le__(self, other, /) -> bool: ... + def __lt__(self, other, /) -> bool: ... + def __ne__(self, other, /) -> bool: ... +@final class Stash: commit_id: Oid message: str raw_message: bytes - def __eq__(self, other) -> bool: ... - def __ge__(self, other) -> bool: ... - def __gt__(self, other) -> bool: ... - def __le__(self, other) -> bool: ... - def __lt__(self, other) -> bool: ... - def __ne__(self, other) -> bool: ... + def __eq__(self, other, /) -> bool: ... + def __ge__(self, other, /) -> bool: ... + def __gt__(self, other, /) -> bool: ... + def __le__(self, other, /) -> bool: ... + def __lt__(self, other, /) -> bool: ... + def __ne__(self, other, /) -> bool: ... +@final class Tag(Object): message: str name: str @@ -818,30 +828,33 @@ context_lines: int = 3, interhunk_lines: int = 0, ) -> Diff: ... - def __contains__(self, other: str) -> bool: ... # Tree_contains - def __getitem__(self, index: str | int) -> Tree | Blob: ... # Tree_subscript + def __contains__(self, other: str, /) -> bool: ... # Tree_contains + def __getitem__(self, index: str | int, /) -> Tree | Blob: ... # Tree_subscript def __iter__(self) -> Iterator[Object]: ... def __len__(self) -> int: ... # Tree_len - def __rtruediv__(self, other: str) -> Tree | Blob: ... - def __truediv__(self, other: str) -> Tree | Blob: ... # Tree_divide + def __rtruediv__(self, other: str, /) -> Tree | Blob: ... + def __truediv__(self, other: str, /) -> Tree | Blob: ... # Tree_divide +@disjoint_base class TreeBuilder: def clear(self) -> None: ... - def get(self, name: str) -> Object: ... + def get(self, name: str, /) -> Object: ... def insert(self, name: str, oid: _OidArg, attr: int) -> None: ... - def remove(self, name: str) -> None: ... + def remove(self, name: str, /) -> None: ... def write(self) -> Oid: ... def __len__(self) -> int: ... +@final class Walker: - def hide(self, oid: _OidArg) -> None: ... - def push(self, oid: _OidArg) -> None: ... + def hide(self, oid: _OidArg, /) -> None: ... + def push(self, oid: _OidArg, /) -> None: ... def reset(self) -> None: ... def simplify_first_parent(self) -> None: ... - def sort(self, mode: SortMode) -> None: ... + def sort(self, mode: SortMode, /) -> None: ... def __iter__(self) -> Iterator[Commit]: ... # Walker: ... def __next__(self) -> Commit: ... +@final class Worktree: is_prunable: bool name: str @@ -854,7 +867,7 @@ def hash(data: bytes | str) -> Oid: ... def hashfile(path: str) -> Oid: ... def init_file_backend(path: str, flags: int = 0) -> object: ... -def reference_is_valid_name(refname: str) -> bool: ... +def reference_is_valid_name(refname: str, /) -> bool: ... def tree_entry_cmp(a: Object, b: Object) -> int: ... def _cache_enums() -> None: ... def filter_register(name: str, filter: type[Filter]) -> None: ... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/pygit2/callbacks.py new/pygit2-1.19.3/pygit2/callbacks.py --- old/pygit2-1.19.2/pygit2/callbacks.py 2026-03-29 15:47:01.116144400 +0200 +++ new/pygit2-1.19.3/pygit2/callbacks.py 2026-06-13 09:30:16.561183500 +0200 @@ -66,7 +66,7 @@ from collections.abc import Callable, Generator from contextlib import contextmanager from functools import wraps -from typing import TYPE_CHECKING, Optional, ParamSpec, TypeVar +from typing import TYPE_CHECKING, Any, Optional, ParamSpec, TypeVar # pygit2 from ._pygit2 import DiffFile, Oid @@ -81,7 +81,6 @@ if TYPE_CHECKING: from pygit2._libgit2.ffi import GitProxyOptionsC - from ._pygit2 import CloneOptions, PushOptions from .remotes import PushUpdate, TransferProgress # # The payload is the way to pass information from the pygit2 API, through @@ -92,7 +91,7 @@ class Payload: repository: Callable | None remote: Callable | None - clone_options: 'CloneOptions' + clone_options: Any def __init__(self, **kw: object) -> None: for key, value in kw.items(): @@ -125,7 +124,7 @@ RemoteCallbacks(certificate=certificate). """ - push_options: 'PushOptions' + push_options: Any def __init__( self, @@ -309,7 +308,7 @@ Raising an exception from this callback will cancel the checkout. The exception will be propagated back and raised by the - Repository.checkout_... call. + ``Repository.checkout_...`` call. Notification callbacks are made prior to modifying any files on disk, so canceling on any notification will still happen prior to any files diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/pygit2/enums.py new/pygit2-1.19.3/pygit2/enums.py --- old/pygit2-1.19.2/pygit2/enums.py 2026-03-29 15:47:01.116711900 +0200 +++ new/pygit2-1.19.3/pygit2/enums.py 2026-06-13 09:30:16.562183400 +0200 @@ -363,7 +363,7 @@ """Flags to control the behavior of diff rename/copy detection.""" FIND_BY_CONFIG = _pygit2.GIT_DIFF_FIND_BY_CONFIG - """ Obey `diff.renames`. Overridden by any other FIND_... flag. """ + """ Obey ``diff.renames``. Overridden by any other ``FIND_...`` flag. """ FIND_RENAMES = _pygit2.GIT_DIFF_FIND_RENAMES """ Look for renames? (`--find-renames`) """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/pygit2/index.py new/pygit2-1.19.3/pygit2/index.py --- old/pygit2-1.19.2/pygit2/index.py 2026-03-29 15:47:01.116711900 +0200 +++ new/pygit2-1.19.3/pygit2/index.py 2026-06-13 09:30:16.562183400 +0200 @@ -255,11 +255,11 @@ centry_ours: ffi.NULL_TYPE | ffi.GitIndexEntryC = ffi.NULL centry_theirs: ffi.NULL_TYPE | ffi.GitIndexEntryC = ffi.NULL if ancestor is not None: - centry_ancestor, _ = ancestor._to_c() + centry_ancestor, path_ancestor = ancestor._to_c() if ours is not None: - centry_ours, _ = ours._to_c() + centry_ours, path_ours = ours._to_c() if theirs is not None: - centry_theirs, _ = theirs._to_c() + centry_theirs, path_theirs = theirs._to_c() err = C.git_index_conflict_add( self._index, centry_ancestor, centry_ours, centry_theirs ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/pygit2/repository.py new/pygit2-1.19.3/pygit2/repository.py --- old/pygit2-1.19.2/pygit2/repository.py 2026-03-29 15:47:01.116937600 +0200 +++ new/pygit2-1.19.3/pygit2/repository.py 2026-06-13 09:30:16.563183500 +0200 @@ -81,7 +81,7 @@ from .remotes import RemoteCollection from .submodules import SubmoduleCollection from .transaction import ReferenceTransaction -from .utils import StrArray, to_bytes +from .utils import StrArray, maybe_string, to_bytes if TYPE_CHECKING: from pygit2._libgit2.ffi import ( @@ -614,7 +614,7 @@ If 'b' is None, by default the working directory is compared to 'a'. If 'cached' is set to True, the index/staging area is used for comparing. - flag + flags A combination of enums.DiffOption constants. context_lines @@ -1278,7 +1278,7 @@ Example:: >>> repo = pygit2.Repository('.') - >>> repo.stash(repo.default_signature(), 'WIP: stashing') + >>> repo.stash(repo.default_signature, 'WIP: stashing') """ opts = ffi.new('git_stash_save_options *') @@ -1347,7 +1347,7 @@ Example:: >>> repo = pygit2.Repository('.') - >>> repo.stash(repo.default_signature(), 'WIP: stashing') + >>> repo.stash(repo.default_signature, 'WIP: stashing') >>> repo.stash_apply(strategy=CheckoutStrategy.ALLOW_CONFLICTS) """ with git_stash_apply_options( @@ -1578,16 +1578,16 @@ # Identity for reference operations # @property - def ident(self): + def ident(self) -> tuple[Optional[str], Optional[str]]: cname = ffi.new('char **') cemail = ffi.new('char **') err = C.git_repository_ident(cname, cemail, self._repo) check_error(err) - return (ffi.string(cname).decode('utf-8'), ffi.string(cemail).decode('utf-8')) + return (maybe_string(cname[0]), maybe_string(cemail[0])) - def set_ident(self, name: str, email: str) -> None: + def set_ident(self, name: Optional[str], email: Optional[str]) -> None: """Set the identity to be used for reference operations. Updates to some references also append data to their diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/pyproject.toml new/pygit2-1.19.3/pyproject.toml --- old/pygit2-1.19.2/pyproject.toml 2026-03-29 15:47:01.116937600 +0200 +++ new/pygit2-1.19.3/pyproject.toml 2026-06-13 09:30:16.563183500 +0200 @@ -9,12 +9,12 @@ archs = ["native"] build-frontend = "default" dependency-versions = "pinned" -environment = {LIBGIT2_VERSION="1.9.2", LIBSSH2_VERSION="1.11.1", OPENSSL_VERSION="3.5.4", LIBGIT2="/project/ci"} +environment = {LIBGIT2="$(pwd)/ci", LIBGIT2_VERSION="1.9.4", LIBSSH2_VERSION="1.11.1", OPENSSL_VERSION="3.5.4"} before-all = "sh build.sh" test-command = "pytest" test-sources = ["test", "pytest.ini"] -before-test = "pip install -r {project}/requirements-test.txt" +before-test = "pip install -r {package}/requirements-test.txt" # Will avoid testing on emulated architectures (specifically ppc64le) # Also, skip testing pypy on macOS arm64 due issue with bootstrapping git config paths # see https://github.com/libgit2/pygit2/issues/1442 @@ -28,18 +28,18 @@ repair-wheel-command = "LD_LIBRARY_PATH=/project/ci/lib auditwheel repair -w {dest_dir} {wheel}" [tool.cibuildwheel.macos] -environment = {LIBGIT2_VERSION="1.9.2", LIBSSH2_VERSION="1.11.1", OPENSSL_VERSION="3.5.4", LIBGIT2="/Users/runner/work/pygit2/pygit2/ci"} -repair-wheel-command = "DYLD_LIBRARY_PATH=/Users/runner/work/pygit2/pygit2/ci/lib delocate-wheel --require-archs {delocate_archs} -w {dest_dir} {wheel}" +repair-wheel-command = "DYLD_LIBRARY_PATH={package}/ci/lib delocate-wheel --require-archs {delocate_archs} -w {dest_dir} {wheel}" [tool.cibuildwheel.windows] environment.LIBGIT2_SRC = "build/libgit2_src" -environment.LIBGIT2_VERSION = "1.9.2" +environment.LIBGIT2_VERSION = "1.9.4" before-all = "powershell -File build.ps1" +before-build = "" [[tool.cibuildwheel.overrides]] select="*-win_amd64" inherit.environment="append" -environment.CMAKE_GENERATOR = "Visual Studio 17 2022" +environment.CMAKE_GENERATOR = "Visual Studio 18 2026" environment.CMAKE_GENERATOR_PLATFORM = "x64" environment.CMAKE_INSTALL_PREFIX = "C:/libgit2_install_x86_64" environment.LIBGIT2 = "C:/libgit2_install_x86_64" @@ -47,7 +47,7 @@ [[tool.cibuildwheel.overrides]] select="*-win32" inherit.environment="append" -environment.CMAKE_GENERATOR = "Visual Studio 17 2022" +environment.CMAKE_GENERATOR = "Visual Studio 18 2026" environment.CMAKE_GENERATOR_PLATFORM = "Win32" environment.CMAKE_INSTALL_PREFIX = "C:/libgit2_install_x86" environment.LIBGIT2 = "C:/libgit2_install_x86" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/src/odb.c new/pygit2-1.19.3/src/odb.c --- old/pygit2-1.19.2/src/odb.c 2026-03-29 15:47:01.117937600 +0200 +++ new/pygit2-1.19.3/src/odb.c 2026-06-13 09:30:16.565183600 +0200 @@ -209,7 +209,7 @@ } PyDoc_STRVAR(Odb_read_header__doc__, - "read_header(oid: Oid) -> tuple[enums.ObjectType, size\n" + "read_header(oid: Oid) -> tuple[enums.ObjectType, int]\n" "\n" "Read the header of an object from the database, without reading its full\n" "contents.\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/src/odb_backend.c new/pygit2-1.19.3/src/odb_backend.c --- old/pygit2-1.19.2/src/odb_backend.c 2026-03-29 15:47:01.118937500 +0200 +++ new/pygit2-1.19.3/src/odb_backend.c 2026-06-13 09:30:16.565183600 +0200 @@ -72,11 +72,13 @@ const char *bytes; Py_ssize_t type_value; - if (!PyArg_ParseTuple(result, "ny#", &type_value, &bytes, sz) || !bytes) { + Py_ssize_t py_sz; + if (!PyArg_ParseTuple(result, "ny#", &type_value, &bytes, &py_sz) || !bytes) { Py_DECREF(result); return GIT_EUSER; } *type = (git_object_t)type_value; + *sz = (size_t)py_sz; *ptr = git_odb_backend_data_alloc(_be, *sz); if (!*ptr) { @@ -106,12 +108,14 @@ // Parse output from callback PyObject *py_oid_out; Py_ssize_t type_value; + Py_ssize_t py_sz; const char *bytes; - if (!PyArg_ParseTuple(result, "ny#O", &type_value, &bytes, sz, &py_oid_out) || !bytes) { + if (!PyArg_ParseTuple(result, "ny#O", &type_value, &bytes, &py_sz, &py_oid_out) || !bytes) { Py_DECREF(result); return GIT_EUSER; } *type = (git_object_t)type_value; + *sz = (size_t)py_sz; *ptr = git_odb_backend_data_alloc(_be, *sz); if (!*ptr) { @@ -255,6 +259,10 @@ // Create the C backend pgit_odb_backend *custom_backend = calloc(1, sizeof(pgit_odb_backend)); + if (custom_backend == NULL) { + PyErr_NoMemory(); + return -1; + } custom_backend->backend.version = GIT_ODB_BACKEND_VERSION; // Fill the member methods diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/src/refdb_backend.c new/pygit2-1.19.3/src/refdb_backend.c --- old/pygit2-1.19.2/src/refdb_backend.c 2026-03-29 15:47:01.118937500 +0200 +++ new/pygit2-1.19.3/src/refdb_backend.c 2026-06-13 09:30:16.566183600 +0200 @@ -36,6 +36,7 @@ #include "wildmatch.h" #include <git2/refdb.h> #include <git2/sys/refdb_backend.h> +#include <git2/sys/errors.h> extern PyTypeObject ReferenceType; extern PyTypeObject RepositoryType; @@ -137,8 +138,12 @@ PyObject *iterator = PyObject_GetIter((PyObject *)be->RefdbBackend); assert(iterator); - struct pygit2_refdb_iterator *pyiter = - calloc(1, sizeof(struct pygit2_refdb_iterator)); + struct pygit2_refdb_iterator *pyiter = calloc(1, sizeof(struct pygit2_refdb_iterator)); + if (pyiter == NULL) { + Py_DECREF(iterator); + git_error_set(GIT_ERROR_NOMEMORY, "out of memory"); + return GIT_ERROR; + } *iter = (git_reference_iterator *)pyiter; pyiter->iterator = iterator; pyiter->base.next = pygit2_refdb_iterator_next; @@ -389,18 +394,20 @@ RefdbBackend_init(RefdbBackend *self, PyObject *args, PyObject *kwds) { if (args && PyTuple_Size(args) > 0) { - PyErr_SetString(PyExc_TypeError, - "RefdbBackend takes no arguments"); + PyErr_SetString(PyExc_TypeError, "RefdbBackend takes no arguments"); return -1; } if (kwds && PyDict_Size(kwds) > 0) { - PyErr_SetString(PyExc_TypeError, - "RefdbBackend takes no keyword arguments"); + PyErr_SetString(PyExc_TypeError, "RefdbBackend takes no keyword arguments"); return -1; } struct pygit2_refdb_backend *be = calloc(1, sizeof(struct pygit2_refdb_backend)); + if (be == NULL) { + PyErr_NoMemory(); + return -1; + } git_refdb_init_backend(&be->backend, GIT_REFDB_BACKEND_VERSION); be->RefdbBackend = (PyObject *)self; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/src/repository.c new/pygit2-1.19.3/src/repository.c --- old/pygit2-1.19.2/src/repository.c 2026-03-29 15:47:01.118937500 +0200 +++ new/pygit2-1.19.3/src/repository.c 2026-06-13 09:30:16.566183600 +0200 @@ -1216,7 +1216,7 @@ } PyDoc_STRVAR(Repository_create_tag__doc__, - "create_tag(name: str, oid: Oid, type: enums.ObjectType, tagger: Signature[, message: str]) -> Oid\n" + "create_tag(name: str, oid: Oid, type: enums.ObjectType, tagger: Signature, message: str) -> Oid\n" "\n" "Create a new tag object, return its oid."); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/src/utils.h new/pygit2-1.19.3/src/utils.h --- old/pygit2-1.19.2/src/utils.h 2026-03-29 15:47:01.119937700 +0200 +++ new/pygit2-1.19.3/src/utils.h 2026-06-13 09:30:16.566183600 +0200 @@ -128,23 +128,6 @@ {#attr, attr_type, offsetof(type, attr), READONLY, PyDoc_STR(docstr)} -/* Helpers for memory allocation */ -#define CALLOC(ptr, num, size, label) \ - ptr = calloc((num), size);\ - if (ptr == NULL) {\ - err = GIT_ERROR;\ - giterr_set_oom();\ - goto label;\ - } - -#define MALLOC(ptr, size, label) \ - ptr = malloc(size);\ - if (ptr == NULL) {\ - err = GIT_ERROR;\ - giterr_set_oom();\ - goto label;\ - } - /* Helpers to make type init shorter. */ #define INIT_TYPE(type, base, new) \ type.tp_base = base; \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/test/test_refdb_backend.py new/pygit2-1.19.3/test/test_refdb_backend.py --- old/pygit2-1.19.2/test/test_refdb_backend.py 2026-03-29 15:47:01.123324200 +0200 +++ new/pygit2-1.19.3/test/test_refdb_backend.py 2026-06-13 09:30:16.571183700 +0200 @@ -25,7 +25,7 @@ """Tests for Refdb objects.""" -from collections.abc import Generator, Iterator +from collections.abc import Generator from pathlib import Path import pytest @@ -77,9 +77,6 @@ def ensure_log(self, ref_name: str) -> bool: return self.source.ensure_log(ref_name) - def __iter__(self) -> Iterator[Reference]: - return iter(self.source) - @pytest.fixture def repo(testrepo: Repository) -> Generator[Repository, None, None]: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pygit2-1.19.2/test/test_repository.py new/pygit2-1.19.3/test/test_repository.py --- old/pygit2-1.19.2/test/test_repository.py 2026-03-29 15:47:01.123324200 +0200 +++ new/pygit2-1.19.3/test/test_repository.py 2026-06-13 09:30:16.571183700 +0200 @@ -641,6 +641,19 @@ assert '[email protected]' == sig.email +def test_ident_get_set(testrepo: Repository) -> None: + # By default, reflog identity should be unset. + assert testrepo.ident == (None, None) + + cname = 'C O Mitter' + cemail = '[email protected]' + testrepo.set_ident(cname, cemail) + assert testrepo.ident == (cname, cemail) + + testrepo.set_ident(None, None) + assert testrepo.ident == (None, None) + + def test_new_repo(tmp_path: Path) -> None: repo = init_repository(tmp_path, False)
