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)
 

Reply via email to