pygit2 1.20.0__tar.gz → 1.21.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. {pygit2-1.20.0 → pygit2-1.21.0}/AGENTS.md +12 -12
  2. {pygit2-1.20.0 → pygit2-1.21.0}/AUTHORS.md +7 -3
  3. {pygit2-1.20.0 → pygit2-1.21.0}/CHANGELOG.md +74 -0
  4. pygit2-1.21.0/Makefile +7 -0
  5. {pygit2-1.20.0 → pygit2-1.21.0}/PKG-INFO +3 -2
  6. {pygit2-1.20.0 → pygit2-1.21.0}/README.md +1 -1
  7. {pygit2-1.20.0 → pygit2-1.21.0}/SPONSORS.md +2 -0
  8. pygit2-1.21.0/build.ps1 +51 -0
  9. {pygit2-1.20.0 → pygit2-1.21.0}/build.sh +49 -42
  10. pygit2-1.21.0/mypy-stubtest.ini +28 -0
  11. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/__init__.py +24 -5
  12. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/_build.py +9 -1
  13. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/_pygit2.pyi +10 -3
  14. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/_run.py +3 -5
  15. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/blob.py +14 -4
  16. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/branches.py +6 -4
  17. pygit2-1.21.0/pygit2/config.py +1023 -0
  18. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/config.h +1 -0
  19. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/errors.h +41 -2
  20. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/enums.py +4 -0
  21. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/errors.py +63 -11
  22. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/references.py +5 -1
  23. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/repository.py +16 -19
  24. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/submodules.py +6 -2
  25. {pygit2-1.20.0 → pygit2-1.21.0}/pyproject.toml +8 -4
  26. {pygit2-1.20.0 → pygit2-1.21.0}/setup.py +6 -5
  27. {pygit2-1.20.0 → pygit2-1.21.0}/src/blob.c +9 -4
  28. {pygit2-1.20.0 → pygit2-1.21.0}/src/commit.c +2 -2
  29. {pygit2-1.20.0 → pygit2-1.21.0}/src/diff.c +61 -6
  30. {pygit2-1.20.0 → pygit2-1.21.0}/src/diff.h +1 -1
  31. {pygit2-1.20.0 → pygit2-1.21.0}/src/error.c +35 -5
  32. {pygit2-1.20.0 → pygit2-1.21.0}/src/odb.c +12 -9
  33. {pygit2-1.20.0 → pygit2-1.21.0}/src/odb_backend.c +155 -71
  34. {pygit2-1.20.0 → pygit2-1.21.0}/src/patch.c +7 -2
  35. {pygit2-1.20.0 → pygit2-1.21.0}/src/pygit2.c +13 -2
  36. {pygit2-1.20.0 → pygit2-1.21.0}/src/refdb_backend.c +4 -2
  37. {pygit2-1.20.0 → pygit2-1.21.0}/src/reference.c +4 -2
  38. {pygit2-1.20.0 → pygit2-1.21.0}/src/repository.c +3 -1
  39. {pygit2-1.20.0 → pygit2-1.21.0}/src/tree.c +1 -1
  40. {pygit2-1.20.0 → pygit2-1.21.0}/src/types.h +2 -0
  41. {pygit2-1.20.0 → pygit2-1.21.0}/src/utils.h +13 -0
  42. {pygit2-1.20.0 → pygit2-1.21.0}/test/conftest.py +6 -0
  43. pygit2-1.21.0/test/data/bigrepo.zip +0 -0
  44. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_blob.py +54 -1
  45. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_branch.py +21 -0
  46. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_branch_empty.py +1 -0
  47. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_config.py +168 -13
  48. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_diff.py +1 -3
  49. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_diff_binary.py +6 -0
  50. pygit2-1.21.0/test/test_errors.py +126 -0
  51. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_nonunicode.py +8 -0
  52. pygit2-1.21.0/test/test_odb_backend.py +358 -0
  53. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_packbuilder.py +1 -0
  54. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_refdb_backend.py +61 -13
  55. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_refs.py +42 -0
  56. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_status.py +44 -0
  57. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_submodule.py +19 -0
  58. {pygit2-1.20.0 → pygit2-1.21.0}/test/utils.py +1 -1
  59. pygit2-1.20.0/Makefile +0 -7
  60. pygit2-1.20.0/build.ps1 +0 -23
  61. pygit2-1.20.0/mypy-stubtest.ini +0 -16
  62. pygit2-1.20.0/pygit2/config.py +0 -428
  63. pygit2-1.20.0/setup.cfg +0 -3
  64. pygit2-1.20.0/test/test_odb_backend.py +0 -171
  65. {pygit2-1.20.0 → pygit2-1.21.0}/CONTRIBUTING.md +0 -0
  66. {pygit2-1.20.0 → pygit2-1.21.0}/COPYING +0 -0
  67. {pygit2-1.20.0 → pygit2-1.21.0}/build_tag.py +0 -0
  68. {pygit2-1.20.0 → pygit2-1.21.0}/mypy.ini +0 -0
  69. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/_libgit2/ffi.pyi +0 -0
  70. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/blame.py +0 -0
  71. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/callbacks.py +0 -0
  72. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/credentials.py +0 -0
  73. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/attr.h +0 -0
  74. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/blame.h +0 -0
  75. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/buffer.h +0 -0
  76. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/callbacks.h +0 -0
  77. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/checkout.h +0 -0
  78. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/clone.h +0 -0
  79. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/commit.h +0 -0
  80. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/common.h +0 -0
  81. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/describe.h +0 -0
  82. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/diff.h +0 -0
  83. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/filter.h +0 -0
  84. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/graph.h +0 -0
  85. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/index.h +0 -0
  86. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/indexer.h +0 -0
  87. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/merge.h +0 -0
  88. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/net.h +0 -0
  89. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/oid.h +0 -0
  90. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/options.h +0 -0
  91. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/pack.h +0 -0
  92. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/proxy.h +0 -0
  93. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/rebase.h +0 -0
  94. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/refspec.h +0 -0
  95. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/remote.h +0 -0
  96. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/repository.h +0 -0
  97. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/revert.h +0 -0
  98. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/stash.h +0 -0
  99. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/strarray.h +0 -0
  100. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/submodule.h +0 -0
  101. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/transaction.h +0 -0
  102. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/transport.h +0 -0
  103. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/decl/types.h +0 -0
  104. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/ffi.py +0 -0
  105. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/filter.py +0 -0
  106. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/index.py +0 -0
  107. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/options.py +0 -0
  108. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/packbuilder.py +0 -0
  109. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/py.typed +0 -0
  110. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/rebase.py +0 -0
  111. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/refspec.py +0 -0
  112. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/remotes.py +0 -0
  113. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/settings.py +0 -0
  114. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/transaction.py +0 -0
  115. {pygit2-1.20.0 → pygit2-1.21.0}/pygit2/utils.py +0 -0
  116. {pygit2-1.20.0 → pygit2-1.21.0}/pytest.ini +0 -0
  117. {pygit2-1.20.0 → pygit2-1.21.0}/requirements-test.txt +0 -0
  118. {pygit2-1.20.0 → pygit2-1.21.0}/requirements-typing.txt +0 -0
  119. {pygit2-1.20.0 → pygit2-1.21.0}/requirements-wheel.txt +0 -0
  120. {pygit2-1.20.0 → pygit2-1.21.0}/requirements.txt +0 -0
  121. {pygit2-1.20.0 → pygit2-1.21.0}/src/branch.c +0 -0
  122. {pygit2-1.20.0 → pygit2-1.21.0}/src/branch.h +0 -0
  123. {pygit2-1.20.0 → pygit2-1.21.0}/src/error.h +0 -0
  124. {pygit2-1.20.0 → pygit2-1.21.0}/src/filter.c +0 -0
  125. {pygit2-1.20.0 → pygit2-1.21.0}/src/filter.h +0 -0
  126. {pygit2-1.20.0 → pygit2-1.21.0}/src/mailmap.c +0 -0
  127. {pygit2-1.20.0 → pygit2-1.21.0}/src/mailmap.h +0 -0
  128. {pygit2-1.20.0 → pygit2-1.21.0}/src/note.c +0 -0
  129. {pygit2-1.20.0 → pygit2-1.21.0}/src/note.h +0 -0
  130. {pygit2-1.20.0 → pygit2-1.21.0}/src/object.c +0 -0
  131. {pygit2-1.20.0 → pygit2-1.21.0}/src/object.h +0 -0
  132. {pygit2-1.20.0 → pygit2-1.21.0}/src/odb.h +0 -0
  133. {pygit2-1.20.0 → pygit2-1.21.0}/src/odb_backend.h +0 -0
  134. {pygit2-1.20.0 → pygit2-1.21.0}/src/oid.c +0 -0
  135. {pygit2-1.20.0 → pygit2-1.21.0}/src/oid.h +0 -0
  136. {pygit2-1.20.0 → pygit2-1.21.0}/src/patch.h +0 -0
  137. {pygit2-1.20.0 → pygit2-1.21.0}/src/refdb.c +0 -0
  138. {pygit2-1.20.0 → pygit2-1.21.0}/src/refdb.h +0 -0
  139. {pygit2-1.20.0 → pygit2-1.21.0}/src/refdb_backend.h +0 -0
  140. {pygit2-1.20.0 → pygit2-1.21.0}/src/reference.h +0 -0
  141. {pygit2-1.20.0 → pygit2-1.21.0}/src/repository.h +0 -0
  142. {pygit2-1.20.0 → pygit2-1.21.0}/src/revspec.c +0 -0
  143. {pygit2-1.20.0 → pygit2-1.21.0}/src/revspec.h +0 -0
  144. {pygit2-1.20.0 → pygit2-1.21.0}/src/signature.c +0 -0
  145. {pygit2-1.20.0 → pygit2-1.21.0}/src/signature.h +0 -0
  146. {pygit2-1.20.0 → pygit2-1.21.0}/src/stash.c +0 -0
  147. {pygit2-1.20.0 → pygit2-1.21.0}/src/tag.c +0 -0
  148. {pygit2-1.20.0 → pygit2-1.21.0}/src/tree.h +0 -0
  149. {pygit2-1.20.0 → pygit2-1.21.0}/src/treebuilder.c +0 -0
  150. {pygit2-1.20.0 → pygit2-1.21.0}/src/treebuilder.h +0 -0
  151. {pygit2-1.20.0 → pygit2-1.21.0}/src/utils.c +0 -0
  152. {pygit2-1.20.0 → pygit2-1.21.0}/src/walker.c +0 -0
  153. {pygit2-1.20.0 → pygit2-1.21.0}/src/walker.h +0 -0
  154. {pygit2-1.20.0 → pygit2-1.21.0}/src/wildmatch.c +0 -0
  155. {pygit2-1.20.0 → pygit2-1.21.0}/src/wildmatch.h +0 -0
  156. {pygit2-1.20.0 → pygit2-1.21.0}/src/worktree.c +0 -0
  157. {pygit2-1.20.0 → pygit2-1.21.0}/src/worktree.h +0 -0
  158. {pygit2-1.20.0 → pygit2-1.21.0}/test/__init__.py +0 -0
  159. {pygit2-1.20.0 → pygit2-1.21.0}/test/data/barerepo.zip +0 -0
  160. {pygit2-1.20.0 → pygit2-1.21.0}/test/data/binaryfilerepo.zip +0 -0
  161. {pygit2-1.20.0 → pygit2-1.21.0}/test/data/blameflagsrepo.zip +0 -0
  162. {pygit2-1.20.0 → pygit2-1.21.0}/test/data/dirtyrepo.zip +0 -0
  163. {pygit2-1.20.0 → pygit2-1.21.0}/test/data/emptyrepo.zip +0 -0
  164. {pygit2-1.20.0 → pygit2-1.21.0}/test/data/encoding.zip +0 -0
  165. {pygit2-1.20.0 → pygit2-1.21.0}/test/data/gpgsigned.zip +0 -0
  166. {pygit2-1.20.0 → pygit2-1.21.0}/test/data/submodulerepo.zip +0 -0
  167. {pygit2-1.20.0 → pygit2-1.21.0}/test/data/testrepo.zip +0 -0
  168. {pygit2-1.20.0 → pygit2-1.21.0}/test/data/testrepoformerging.zip +0 -0
  169. {pygit2-1.20.0 → pygit2-1.21.0}/test/data/testrepopacked.zip +0 -0
  170. {pygit2-1.20.0 → pygit2-1.21.0}/test/data/trailerrepo.zip +0 -0
  171. {pygit2-1.20.0 → pygit2-1.21.0}/test/data/utf8branchrepo.zip +0 -0
  172. {pygit2-1.20.0 → pygit2-1.21.0}/test/keys/pygit2_empty +0 -0
  173. {pygit2-1.20.0 → pygit2-1.21.0}/test/keys/pygit2_empty.pub +0 -0
  174. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_apply_diff.py +0 -0
  175. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_archive.py +0 -0
  176. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_attributes.py +0 -0
  177. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_blame.py +0 -0
  178. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_cherrypick.py +0 -0
  179. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_commit.py +0 -0
  180. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_commit_gpg.py +0 -0
  181. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_commit_trailer.py +0 -0
  182. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_credentials.py +0 -0
  183. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_describe.py +0 -0
  184. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_filter.py +0 -0
  185. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_index.py +0 -0
  186. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_mailmap.py +0 -0
  187. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_merge.py +0 -0
  188. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_note.py +0 -0
  189. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_object.py +0 -0
  190. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_odb.py +0 -0
  191. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_oid.py +0 -0
  192. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_options.py +0 -0
  193. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_patch.py +0 -0
  194. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_patch_encoding.py +0 -0
  195. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_rebase.py +0 -0
  196. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_remote.py +0 -0
  197. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_remote_prune.py +0 -0
  198. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_remote_utf8.py +0 -0
  199. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_repository.py +0 -0
  200. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_repository_bare.py +0 -0
  201. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_repository_custom.py +0 -0
  202. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_repository_empty.py +0 -0
  203. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_revparse.py +0 -0
  204. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_revwalk.py +0 -0
  205. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_settings.py +0 -0
  206. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_signature.py +0 -0
  207. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_tag.py +0 -0
  208. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_transaction.py +0 -0
  209. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_tree.py +0 -0
  210. {pygit2-1.20.0 → pygit2-1.21.0}/test/test_treebuilder.py +0 -0
@@ -10,8 +10,8 @@ and a high-level, Pythonic API for repository manipulation.
10
10
  - **Version**: 1.19.3 (canonical version is defined in `pygit2/_build.py`)
11
11
  - **License**: GPLv2 with linking exception (see `COPYING`)
12
12
  - **Maintainer**: J. David Ibáñez
13
- - **Python Support**: 3.11 – 3.14 and PyPy3 7.3+
14
- - **libgit2 Version**: 1.9.6
13
+ - **Python Support**: 3.11 – 3.15 and PyPy3 7.3+
14
+ - **libgit2 Version**: 1.9.7
15
15
  - **Homepage**: <https://www.pygit2.org/>
16
16
  - **Repository**: <https://github.com/libgit2/pygit2>
17
17
 
@@ -69,7 +69,6 @@ modules:
69
69
  also copies `git2.dll` into the package (see `BuildWithDLLs`).
70
70
  - **`pyproject.toml`** — Build-system requirements, `cibuildwheel`
71
71
  configuration, `ruff` settings, and `codespell` settings.
72
- - **`setup.cfg`** — Legacy pycodestyle configuration.
73
72
  - **`pytest.ini`** — pytest configuration (`--capture=no -ra --verbose`,
74
73
  `testpaths = test/`).
75
74
  - **`mypy.ini`** — mypy configuration with strict settings.
@@ -107,7 +106,7 @@ handles libgit2 compilation via CMake.
107
106
  make
108
107
 
109
108
  # Or manually:
110
- LIBSSH2_VERSION=1.11.1 LIBGIT2_VERSION=1.9.6 sh build.sh
109
+ LIBSSH2_VERSION=1.11.1 LIBGIT2_VERSION=1.9.7 sh build.sh
111
110
 
112
111
  # Build a wheel and bundle the shared libraries into it
113
112
  sh build.sh wheel
@@ -139,8 +138,8 @@ Variables consumed by `build.sh`:
139
138
 
140
139
  - `LIBGIT2_VERSION` — If set, download and build this libgit2 version.
141
140
  - `LIBSSH2_VERSION` — If set, download and build libssh2 with SSH support.
142
- - `OPENSSL_VERSION` — If set, download and build OpenSSL (mainly used for
143
- macOS universal builds on CI).
141
+ - `OPENSSL_VERSION` — If set, download and build OpenSSL (used on Linux and
142
+ macOS CI builds).
144
143
  - `ZLIB_VERSION` — If set, download and build zlib.
145
144
  - `BUILD_TYPE` — CMake build type (default: `Debug`).
146
145
  - `PYTHON` — Python interpreter to use (default: `python3`).
@@ -240,9 +239,10 @@ GitHub Actions workflows live in `.github/workflows/`:
240
239
  Allowed to fail (`continue-on-error`); see issue #812.
241
240
  - **`lint.yml`** — Runs `ruff format --diff`, `ruff check`, and
242
241
  `sh build.sh mypy`.
243
- - **`wheels.yml`** — Uses `cibuildwheel` (`~=3.3`) to build wheels for Linux
242
+ - **`wheels.yml`** — Uses `cibuildwheel` (`~=4.3.1`) to build wheels for Linux
244
243
  (amd64, arm64, ppc64le and riscv64 via QEMU, musl), macOS (intel, arm64,
245
- PyPy), and Windows (x64, x86, arm64). It also builds an sdist, runs a
244
+ PyPy), and Windows (x64, x86, arm64). Linux, macOS and Windows jobs cache
245
+ the compiled dependencies between runs. It also builds an sdist, runs a
246
246
  `twine check` (skipped on version tags), publishes to PyPI, and creates a
247
247
  GitHub Release on version tags (`v*`), with release notes parsed from
248
248
  `CHANGELOG.md` by `.github/workflows/parse_release_notes.py`.
@@ -250,14 +250,13 @@ GitHub Actions workflows live in `.github/workflows/`:
250
250
 
251
251
  The `cibuildwheel` configuration in `pyproject.toml` pins:
252
252
 
253
- - `LIBGIT2_VERSION="1.9.6"`
253
+ - `LIBGIT2_VERSION="1.9.7"`
254
254
  - `LIBSSH2_VERSION="1.11.1"`
255
- - `OPENSSL_VERSION="3.5.7"`
255
+ - `OPENSSL_VERSION="3.5.9"`
256
256
 
257
257
  and skips `*musllinux_ppc64le` plus testing on `*-*linux_ppc64le`,
258
258
  `*-*linux_riscv64` and `pp*-macosx_arm64`. On Windows it uses the
259
- `Visual Studio 18 2026` CMake generator for x64/x86 and
260
- `Visual Studio 17 2022` for ARM64.
259
+ `Visual Studio 18 2026` CMake generator for x64/x86 and ARM64.
261
260
 
262
261
  ## Security Considerations
263
262
 
@@ -272,6 +271,7 @@ and skips `*musllinux_ppc64le` plus testing on `*-*linux_ppc64le`,
272
271
 
273
272
  ## Git Commits
274
273
 
274
+ - Do not run `git commit` or create commits unless the user explicitly asks for it.
275
275
  - Commits created by an AI agent must end with the `Assisted-by:` trailer.
276
276
  Human-authored commits do not need it.
277
277
 
@@ -14,9 +14,9 @@ Authors:
14
14
  Brandon Milton
15
15
  Daniel Rodríguez Troitiño
16
16
  Brendan Doherty
17
+ Christian Boos
17
18
  Peter Rowlands
18
19
  Richo Healey
19
- Christian Boos
20
20
  Julien Miotte
21
21
  Nick Hynes
22
22
  Richard Möhn
@@ -42,6 +42,7 @@ Authors:
42
42
  Bernardo Heynemann
43
43
  John Szakmeister
44
44
  Nabijacz Leweli
45
+ Nicholas Williams
45
46
  Simon Cozens
46
47
  Vlad Temian
47
48
  WANG Xuerui
@@ -60,6 +61,7 @@ Authors:
60
61
  David Versmisse
61
62
  Grégory Herrero
62
63
  Mikhail Yushkovskiy
64
+ Or Hayat
63
65
  Robin Stocker
64
66
  Rohit Sanjay
65
67
  Rémi Duraffort
@@ -88,6 +90,7 @@ Authors:
88
90
  Petr Viktorin
89
91
  Robert Hölzl
90
92
  Ron Cohen
93
+ Roshan Ramani
91
94
  Sebastian Böhm
92
95
  Sukhman Bhuller
93
96
  Thomas Kluyver
@@ -126,8 +129,8 @@ Authors:
126
129
  Marcel Waldvogel
127
130
  Masud Rahman
128
131
  Michael Sondergaard
132
+ Michal Koutný
129
133
  Natanael Arndt
130
- Nick Williams
131
134
  Ondřej Nový
132
135
  Sarath Lakshman
133
136
  Steve Kieffer
@@ -200,7 +203,9 @@ Authors:
200
203
  Kyriakos Oikonomakos
201
204
  Lance Eftink
202
205
  Legorooj
206
+ Logan Hunt
203
207
  Lukas Berk
208
+ Marius Gedminas
204
209
  Martin von Zweigbergk
205
210
  Mathieu Bridon
206
211
  Mathieu Pillard
@@ -216,7 +221,6 @@ Authors:
216
221
  Nikolai Zujev
217
222
  Nils Philippsen
218
223
  Noah Fontes
219
- Or Hayat
220
224
  Óscar San José
221
225
  Patrick Lühne
222
226
  Paul Wagland
@@ -1,3 +1,77 @@
1
+ # 1.21.0 (2026-11-04)
2
+
3
+ - Add support for Python 3.15
4
+ [#1498](https://github.com/libgit2/pygit2/pull/1498)
5
+
6
+ - New `Config` subclasses: `DefaultConfig` for the default configuration and
7
+ `RepositoryConfig` for repository configurations
8
+ [#1501](https://github.com/libgit2/pygit2/pull/1501)
9
+
10
+ - Fix `ConfigEntry` retaining `git_config_entry` pointers owned by config
11
+ iterators, which could make entry values change unexpectedly and cause
12
+ crashes; values are now copied eagerly
13
+ [#1499](https://github.com/libgit2/pygit2/pull/1499)
14
+
15
+ - Fix custom ODB backends: acquire the GIL when calling back into Python,
16
+ and fix `write_cb`'s type argument
17
+ [#1496](https://github.com/libgit2/pygit2/pull/1496)
18
+
19
+ - Fix `References.get()`, `Branches.get()`, and the `in` operator on both
20
+ collections raising `InvalidSpecError` for invalid names; they now return
21
+ `None` and `False` respectively, as documented
22
+ [#1495](https://github.com/libgit2/pygit2/pull/1495)
23
+
24
+ - Fix `sh build.sh stubtest`
25
+ [#1492](https://github.com/libgit2/pygit2/pull/1492)
26
+
27
+ - Wheels: Build the bundled libgit2 and libssh2 in Release mode instead of Debug
28
+ [#1497](https://github.com/libgit2/pygit2/pull/1497)
29
+
30
+ - Wheels: Update OpenSSL to 3.5.9
31
+ [#1506](https://github.com/libgit2/pygit2/issues/1506)
32
+
33
+
34
+ # 1.20.1 (2026-09-12)
35
+
36
+ - Update wheels to libgit2 1.9.7
37
+
38
+ - New exception hierarchy: `AlreadyExistsError`, `InvalidSpecError`,
39
+ `InvalidError`, `NotFoundError`, `AmbiguousError`, `AuthError`, and
40
+ `CertificateError` all inherit from `GitError` and the appropriate Python
41
+ built-in exception (`ValueError`/`KeyError`) for backward compatibility
42
+ [#830](https://github.com/libgit2/pygit2/issues/830)
43
+
44
+ - Fix `DiffDelta.is_binary` and `DiffDelta.flags` returning stale values for
45
+ deltas obtained from `Diff.deltas`; flags are now loaded lazily
46
+ [#962](https://github.com/libgit2/pygit2/issues/962)
47
+ [#1100](https://github.com/libgit2/pygit2/pull/1100)
48
+
49
+ - Fix `repo.submodules.get()` and `name in repo.submodules` raising
50
+ `AlreadyExistsError` when a repository exists at the submodule path but was
51
+ never registered as a submodule; they now return `None` and `False`
52
+ respectively as documented
53
+ [#1487](https://github.com/libgit2/pygit2/pull/1487)
54
+
55
+ - Fix `BlobIO` cleanup deadlock on partial reads
56
+ [#1488](https://github.com/libgit2/pygit2/issues/1488)
57
+ [#1491](https://github.com/libgit2/pygit2/pull/1491)
58
+
59
+ - Fix leaks and crashes in error paths
60
+ [#1478](https://github.com/libgit2/pygit2/issues/1478)
61
+ [#1479](https://github.com/libgit2/pygit2/issues/1479)
62
+ [#1480](https://github.com/libgit2/pygit2/issues/1480)
63
+ [#1481](https://github.com/libgit2/pygit2/issues/1481)
64
+
65
+ - Fix custom ODB and refdb backend callbacks overwriting a pending Python
66
+ exception (e.g. `RuntimeError`) with a stale libgit2 error message.
67
+
68
+ - Documentation fixes
69
+ [#1490](https://github.com/libgit2/pygit2/pull/1490)
70
+
71
+ - CI (macOS): build architecture-specific OpenSSL/libssh2/libgit2
72
+ dependencies instead of universal binaries, producing smaller wheels.
73
+
74
+
1
75
  # 1.20.0 (2026-08-08)
2
76
 
3
77
  - New `RemoteCallbacks.custom_headers()`
pygit2-1.21.0/Makefile ADDED
@@ -0,0 +1,7 @@
1
+ .PHONY: build html
2
+
3
+ build:
4
+ OPENSSL_VERSION=3.5.9 LIBSSH2_VERSION=1.11.1 LIBGIT2_VERSION=1.9.7 sh build.sh
5
+
6
+ html: build
7
+ make -C docs html
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pygit2
3
- Version: 1.20.0
3
+ Version: 1.21.0
4
4
  Summary: Python bindings for libgit2.
5
5
  Home-page: https://github.com/libgit2/pygit2
6
6
  Maintainer: J. David Ibáñez
@@ -18,6 +18,7 @@ Classifier: Programming Language :: Python :: 3.11
18
18
  Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Programming Language :: Python :: 3.13
20
20
  Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Programming Language :: Python :: 3.15
21
22
  Classifier: Programming Language :: Python :: Implementation :: PyPy
22
23
  Classifier: Programming Language :: Python :: Implementation :: CPython
23
24
  Classifier: Topic :: Software Development :: Version Control
@@ -44,7 +45,7 @@ Dynamic: summary
44
45
  # pygit2 - libgit2 bindings in Python
45
46
 
46
47
  Bindings to the libgit2 shared library, implements Git plumbing.
47
- Supports Python 3.11 to 3.14 and PyPy3 7.3+
48
+ Supports Python 3.11 to 3.15 and PyPy3 7.3+
48
49
 
49
50
  [![test-ci-badge][test-ci-badge]][test-ci-link]
50
51
  [![deploy-ci-badge][deploy-ci-badge]][deploy-ci-link]
@@ -1,7 +1,7 @@
1
1
  # pygit2 - libgit2 bindings in Python
2
2
 
3
3
  Bindings to the libgit2 shared library, implements Git plumbing.
4
- Supports Python 3.11 to 3.14 and PyPy3 7.3+
4
+ Supports Python 3.11 to 3.15 and PyPy3 7.3+
5
5
 
6
6
  [![test-ci-badge][test-ci-badge]][test-ci-link]
7
7
  [![deploy-ci-badge][deploy-ci-badge]][deploy-ci-link]
@@ -1,5 +1,7 @@
1
1
  Friends of pygit2:
2
2
 
3
+ - [William Bowers](https://github.com/ralian)
4
+
3
5
  - Add your name to the list,
4
6
  [become a friend of pygit2](https://github.com/sponsors/jdavid).
5
7
 
@@ -0,0 +1,51 @@
1
+ $ErrorActionPreference = 'Stop'
2
+
3
+ $LIBGIT2_VERSION = $env:LIBGIT2_VERSION
4
+ $LIBGIT2_SRC = $env:LIBGIT2_SRC
5
+ if (-not $LIBGIT2_SRC) {
6
+ $LIBGIT2_SRC = "build/libgit2_src"
7
+ }
8
+
9
+ # Prefer CMAKE_INSTALL_PREFIX, then LIBGIT2, then the default Program Files location.
10
+ $INSTALL_PREFIX = $env:CMAKE_INSTALL_PREFIX
11
+ if (-not $INSTALL_PREFIX) {
12
+ $INSTALL_PREFIX = $env:LIBGIT2
13
+ }
14
+ if (-not $INSTALL_PREFIX) {
15
+ $INSTALL_PREFIX = "$env:ProgramFiles\libgit2"
16
+ }
17
+
18
+ # Use cached dependencies if they match the requested version.
19
+ if ((Test-Path -Path "$INSTALL_PREFIX\versions.txt") -and $LIBGIT2_VERSION) {
20
+ $cached = Get-Content "$INSTALL_PREFIX\versions.txt"
21
+ $matches = $cached | Select-String "^LIBGIT2_VERSION=$LIBGIT2_VERSION$"
22
+ if ($matches) {
23
+ Write-Host "Using cached dependencies"
24
+ exit 0
25
+ }
26
+ }
27
+
28
+ if (!(Test-Path -Path "build")) {
29
+ # in case the pygit2 package build/ workspace has not been created by cibuildwheel yet
30
+ mkdir build
31
+ }
32
+ if (Test-Path -Path "$LIBGIT2_SRC") {
33
+ Set-Location "$LIBGIT2_SRC"
34
+ # for local runs, reuse build/libgit_src if it exists
35
+ if (Test-Path -Path build) {
36
+ # purge previous build env (likely for a different arch type)
37
+ Remove-Item -Recurse -Force build
38
+ }
39
+ # ensure we are checked out to the right version
40
+ git fetch --depth=1 --tags
41
+ git checkout "v$LIBGIT2_VERSION"
42
+ } else {
43
+ # from a fresh run (like in CI)
44
+ git clone --depth=1 -b "v$LIBGIT2_VERSION" https://github.com/libgit2/libgit2.git $LIBGIT2_SRC
45
+ Set-Location "$LIBGIT2_SRC"
46
+ }
47
+ cmake -B build -S . -DBUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX="$INSTALL_PREFIX"
48
+ cmake --build build/ --config=Release --target install
49
+
50
+ # Record version so the cache can be reused.
51
+ "LIBGIT2_VERSION=$LIBGIT2_VERSION" | Set-Content "$INSTALL_PREFIX\versions.txt" -NoNewline
@@ -14,7 +14,7 @@
14
14
  # LIBSSH2_VERSION=<Version> - Build the given version of libssh2
15
15
  # LIBGIT2_VERSION=<Version> - Build the given version of libgit2
16
16
  # OPENSSL_VERSION=<Version> - Build the given version of OpenSSL
17
- # (only needed for Mac universal on CI)
17
+ # (used on Linux and macOS CI builds)
18
18
  #
19
19
  # Examples.
20
20
  #
@@ -22,14 +22,14 @@
22
22
  #
23
23
  # sh build.sh
24
24
  #
25
- # Build libgit2 1.9.6 (will use libssh2 if available), then build pygit2
25
+ # Build libgit2 1.9.7 (will use libssh2 if available), then build pygit2
26
26
  # inplace:
27
27
  #
28
- # LIBGIT2_VERSION=1.9.6 sh build.sh
28
+ # LIBGIT2_VERSION=1.9.7 sh build.sh
29
29
  #
30
- # Build libssh2 1.11.1 and libgit2 1.9.6, then build pygit2 inplace:
30
+ # Build libssh2 1.11.1 and libgit2 1.9.7, then build pygit2 inplace:
31
31
  #
32
- # LIBSSH2_VERSION=1.11.1 LIBGIT2_VERSION=1.9.6 sh build.sh
32
+ # LIBSSH2_VERSION=1.11.1 LIBGIT2_VERSION=1.9.7 sh build.sh
33
33
  #
34
34
  # Build inplace and run the tests:
35
35
  #
@@ -82,8 +82,21 @@ if [ "$CIBUILDWHEEL" = "1" ]; then
82
82
  apk add --no-cache perl
83
83
  fi
84
84
  fi
85
- rm -rf ci
86
- mkdir ci || true
85
+
86
+ # Use cached dependencies if they match the requested versions and build type.
87
+ if [ -f ci/versions.txt ] && \
88
+ grep -q "^LIBGIT2_VERSION=$LIBGIT2_VERSION$" ci/versions.txt && \
89
+ grep -q "^LIBSSH2_VERSION=$LIBSSH2_VERSION$" ci/versions.txt && \
90
+ grep -q "^OPENSSL_VERSION=$OPENSSL_VERSION$" ci/versions.txt && \
91
+ grep -q "^BUILD_TYPE=$BUILD_TYPE$" ci/versions.txt; then
92
+ echo "Using cached dependencies"
93
+ exit 0
94
+ fi
95
+
96
+ # The ci directory may be a bind-mount (e.g. inside cibuildwheel), so
97
+ # remove its contents but keep the directory itself.
98
+ rm -rf ci/* ci/.[!.]* ci/..?* 2>/dev/null || true
99
+ mkdir -p ci
87
100
  cd ci
88
101
  else
89
102
  # Create a virtual environment
@@ -110,31 +123,24 @@ if [ -n "$OPENSSL_VERSION" ]; then
110
123
  wget https://www.openssl.org/source/$FILENAME.tar.gz -N --no-check-certificate
111
124
 
112
125
  if [ "$KERNEL" = "Darwin" ]; then
126
+ # Build OpenSSL for the host architecture only.
113
127
  tar xf $FILENAME.tar.gz
114
- mv $FILENAME openssl-x86
115
-
116
- tar xf $FILENAME.tar.gz
117
- mv $FILENAME openssl-arm
118
-
119
- cd openssl-x86
120
- ./Configure darwin64-x86_64-cc shared
121
- make
122
- cd ../openssl-arm
123
- ./Configure enable-rc5 zlib darwin64-arm64-cc no-asm
128
+ cd $FILENAME
129
+ if [ "$ARCH" = "arm64" ]; then
130
+ ./Configure enable-rc5 zlib darwin64-arm64-cc no-asm shared --prefix=$PREFIX --libdir=$PREFIX/lib
131
+ else
132
+ ./Configure darwin64-x86_64-cc shared --prefix=$PREFIX --libdir=$PREFIX/lib
133
+ fi
124
134
  make
125
- cd ..
126
-
127
- mkdir openssl-universal
128
-
129
- LIBSSL=$(basename openssl-x86/libssl.*.dylib)
130
- lipo -create openssl-x86/libssl.*.dylib openssl-arm/libssl.*.dylib -output openssl-universal/$LIBSSL
131
- LIBCRYPTO=$(basename openssl-x86/libcrypto.*.dylib)
132
- lipo -create openssl-x86/libcrypto.*.dylib openssl-arm/libcrypto.*.dylib -output openssl-universal/$LIBCRYPTO
133
- cd openssl-universal
134
- install_name_tool -id "@rpath/$LIBSSL" $LIBSSL
135
- install_name_tool -id "@rpath/$LIBCRYPTO" $LIBCRYPTO
136
- OPENSSL_PREFIX=$(pwd)
137
- cd ..
135
+ make install
136
+ OPENSSL_PREFIX=$PREFIX
137
+ # Set install names so delocate can bundle the libraries.
138
+ cd $PREFIX/lib
139
+ LIBSSL=$(find . -maxdepth 1 -name 'libssl.*.dylib' -type f | head -n1 | sed 's|^\./||')
140
+ LIBCRYPTO=$(find . -maxdepth 1 -name 'libcrypto.*.dylib' -type f | head -n1 | sed 's|^\./||')
141
+ install_name_tool -id "@rpath/$LIBSSL" "$LIBSSL"
142
+ install_name_tool -id "@rpath/$LIBCRYPTO" "$LIBCRYPTO"
143
+ cd ../..
138
144
  else
139
145
  # Linux
140
146
  tar xf $FILENAME.tar.gz
@@ -154,20 +160,19 @@ if [ -n "$LIBSSH2_VERSION" ]; then
154
160
  tar xf $FILENAME.tar.gz
155
161
  cd $FILENAME
156
162
  if [ "$KERNEL" = "Darwin" ] && [ "$CIBUILDWHEEL" = "1" ]; then
157
- cmake . \
163
+ CMAKE_PREFIX_PATH=$PREFIX cmake . \
158
164
  -DCMAKE_INSTALL_PREFIX=$PREFIX \
159
165
  -DBUILD_SHARED_LIBS=ON \
160
166
  -DBUILD_EXAMPLES=OFF \
161
- -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
162
- -DOPENSSL_CRYPTO_LIBRARY="../openssl-universal/$LIBCRYPTO" \
163
- -DOPENSSL_SSL_LIBRARY="../openssl-universal/$LIBSSL" \
164
- -DOPENSSL_INCLUDE_DIR="../openssl-x86/include" \
167
+ -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
168
+ -DCMAKE_OSX_ARCHITECTURES="$ARCH" \
165
169
  -DBUILD_TESTING=OFF
166
170
  else
167
171
  cmake . \
168
172
  -DCMAKE_INSTALL_PREFIX=$PREFIX \
169
173
  -DBUILD_SHARED_LIBS=ON \
170
174
  -DBUILD_EXAMPLES=OFF \
175
+ -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
171
176
  -DBUILD_TESTING=OFF
172
177
  fi
173
178
  cmake --build . --target install
@@ -186,14 +191,11 @@ if [ -n "$LIBGIT2_VERSION" ]; then
186
191
  mkdir -p build
187
192
  cd build
188
193
  if [ "$KERNEL" = "Darwin" ] && [ "$CIBUILDWHEEL" = "1" ]; then
189
- CMAKE_PREFIX_PATH=$OPENSSL_PREFIX:$PREFIX cmake .. \
194
+ CMAKE_PREFIX_PATH=$PREFIX cmake .. \
190
195
  -DBUILD_SHARED_LIBS=ON \
191
196
  -DBUILD_TESTS=OFF \
192
197
  -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
193
- -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
194
- -DOPENSSL_CRYPTO_LIBRARY="../openssl-universal/$LIBCRYPTO" \
195
- -DOPENSSL_SSL_LIBRARY="../openssl-universal/$LIBSSL" \
196
- -DOPENSSL_INCLUDE_DIR="../openssl-x86/include" \
198
+ -DCMAKE_OSX_ARCHITECTURES="$ARCH" \
197
199
  -DCMAKE_INSTALL_PREFIX=$PREFIX \
198
200
  -DUSE_SSH=$USE_SSH
199
201
  else
@@ -212,9 +214,14 @@ if [ -n "$LIBGIT2_VERSION" ]; then
212
214
  fi
213
215
 
214
216
  if [ "$CIBUILDWHEEL" = "1" ]; then
217
+ # Record versions so the cache can be reused.
218
+ cat > $PREFIX/versions.txt <<EOF
219
+ LIBGIT2_VERSION=$LIBGIT2_VERSION
220
+ LIBSSH2_VERSION=$LIBSSH2_VERSION
221
+ OPENSSL_VERSION=$OPENSSL_VERSION
222
+ BUILD_TYPE=$BUILD_TYPE
223
+ EOF
215
224
  if [ "$KERNEL" = "Darwin" ]; then
216
- cp $OPENSSL_PREFIX/*.dylib $PREFIX/lib/
217
- cp $OPENSSL_PREFIX/*.dylib $PREFIX/lib/
218
225
  echo "PREFIX " $PREFIX
219
226
  echo "OPENSSL_PREFIX" $OPENSSL_PREFIX
220
227
  ls -l $PREFIX
@@ -0,0 +1,28 @@
1
+ # Config file for testing the stub file (_pygit2.pyi) with "stubtest"
2
+ # (tool shipped with mypy).
3
+ #
4
+ # Run "build.sh stubtest", or:
5
+ # stubtest --mypy-config-file test/mypy-stubtest.ini pygit2._pygit2
6
+ #
7
+ # Format info:
8
+ # https://mypy.readthedocs.io/en/stable/config_file.html
9
+
10
+ [mypy]
11
+ warn_unused_configs = True
12
+ disallow_any_explicit = True
13
+
14
+ # don't follow import pygit2 from _pygit2.pyi, we only want to check the pyi file.
15
+ [mypy-pygit2]
16
+ follow_imports = skip
17
+
18
+ # The stub imports names from the package (pygit2.Index) and from the cffi
19
+ # binding stub, so those modules enter the build even though stubtest only
20
+ # reads _pygit2.pyi. disallow_any_explicit above is about the stub under test;
21
+ # applying it to the rest of the package is what stopped stubtest running at
22
+ # all once pygit2/_libgit2/ffi.pyi arrived.
23
+ [mypy-pygit2.*]
24
+ disallow_any_explicit = False
25
+
26
+ # ... except the stub under test, which is the point of the setting.
27
+ [mypy-pygit2._pygit2]
28
+ disallow_any_explicit = True
@@ -248,7 +248,6 @@ from ._pygit2 import (
248
248
  LIBGIT2_VER_MINOR,
249
249
  LIBGIT2_VER_REVISION,
250
250
  LIBGIT2_VERSION,
251
- AlreadyExistsError,
252
251
  Blob,
253
252
  Branch,
254
253
  Commit,
@@ -259,8 +258,6 @@ from ._pygit2 import (
259
258
  DiffLine,
260
259
  DiffStats,
261
260
  FilterSource,
262
- GitError,
263
- InvalidSpecError,
264
261
  Mailmap,
265
262
  Note,
266
263
  Object,
@@ -304,9 +301,24 @@ from .callbacks import (
304
301
  git_fetch_options,
305
302
  git_proxy_options,
306
303
  )
307
- from .config import Config
304
+ from .config import (
305
+ Config,
306
+ DefaultConfig,
307
+ RepositoryConfig,
308
+ )
308
309
  from .credentials import *
309
- from .errors import Passthrough, check_error
310
+ from .errors import (
311
+ AlreadyExistsError,
312
+ AmbiguousError,
313
+ AuthError,
314
+ CertificateError,
315
+ GitError,
316
+ InvalidError,
317
+ InvalidSpecError,
318
+ NotFoundError,
319
+ Passthrough,
320
+ check_error,
321
+ )
310
322
  from .ffi import C, ffi
311
323
  from .filter import Filter
312
324
  from .index import Index, IndexEntry
@@ -592,9 +604,13 @@ __all__ = (
592
604
  'Object',
593
605
  'Reference',
594
606
  'AlreadyExistsError',
607
+ 'AmbiguousError',
608
+ 'AuthError',
595
609
  'Blob',
596
610
  'Branch',
611
+ 'CertificateError',
597
612
  'Commit',
613
+ 'DefaultConfig',
598
614
  'Diff',
599
615
  'DiffDelta',
600
616
  'DiffFile',
@@ -602,9 +618,11 @@ __all__ = (
602
618
  'DiffLine',
603
619
  'DiffStats',
604
620
  'GitError',
621
+ 'InvalidError',
605
622
  'InvalidSpecError',
606
623
  'Mailmap',
607
624
  'Note',
625
+ 'NotFoundError',
608
626
  'Odb',
609
627
  'OdbBackend',
610
628
  'OdbBackendLoose',
@@ -928,6 +946,7 @@ __all__ = (
928
946
  'Remote',
929
947
  'repository',
930
948
  'Repository',
949
+ 'RepositoryConfig',
931
950
  'branches',
932
951
  'references',
933
952
  'settings',
@@ -34,7 +34,7 @@ from pathlib import Path
34
34
  #
35
35
  # The version number of pygit2
36
36
  #
37
- __version__ = '1.20.0'
37
+ __version__ = '1.21.0'
38
38
 
39
39
 
40
40
  #
@@ -70,5 +70,13 @@ def get_libgit2_paths() -> tuple[Path, dict[str, list[str]]]:
70
70
  'libraries': ['git2'],
71
71
  'include_dirs': [str(x) for x in include_dirs],
72
72
  'library_dirs': [str(x) for x in library_dirs],
73
+ # For debugging memory issues (segfaults) during development, uncomment the
74
+ # following lines and rebuild everything. YMMV
75
+ # 'extra_compile_args': [
76
+ # '-fsanitize=address',
77
+ # '-fsanitize-address-use-after-scope',
78
+ # '-fsanitize-address-use-odr-indicator',
79
+ # ],
80
+ # 'extra_link_args': ['-fsanitize=address'],
73
81
  },
74
82
  )
@@ -331,7 +331,10 @@ class Reference:
331
331
  def __lt__(self, other, /) -> bool: ...
332
332
  def __ne__(self, other, /) -> bool: ...
333
333
 
334
- class AlreadyExistsError(ValueError): ...
334
+ class AlreadyExistsError(GitError, ValueError): ...
335
+ class AmbiguousError(GitError, ValueError): ...
336
+ class AuthError(GitError): ...
337
+ class InvalidError(GitError, ValueError): ...
335
338
 
336
339
  @final
337
340
  class Blob(Object):
@@ -376,6 +379,8 @@ class Branch(Reference): # type: ignore[misc]
376
379
  def is_head(self) -> bool: ...
377
380
  def rename(self, name: str, force: bool = False) -> 'Branch': ... # type: ignore[override]
378
381
 
382
+ class CertificateError(GitError): ...
383
+
379
384
  @final
380
385
  class Commit(_ObjectBase[GitCommitC]):
381
386
  _pointer: _Pointer[GitCommitC]
@@ -421,7 +426,7 @@ class Diff:
421
426
  @final
422
427
  class DiffDelta:
423
428
  flags: DiffFlag
424
- is_binary: bool
429
+ is_binary: bool | None
425
430
  nfiles: int
426
431
  new_file: DiffFile
427
432
  old_file: DiffFile
@@ -476,7 +481,7 @@ class FilterSource:
476
481
  flags: int
477
482
 
478
483
  class GitError(Exception): ...
479
- class InvalidSpecError(ValueError): ...
484
+ class InvalidSpecError(GitError, ValueError): ...
480
485
 
481
486
  @final
482
487
  class Mailmap:
@@ -505,6 +510,8 @@ class Note:
505
510
  self, author: Signature, committer: Signature, ref: str = 'refs/notes/commits'
506
511
  ) -> None: ...
507
512
 
513
+ class NotFoundError(GitError, KeyError): ...
514
+
508
515
  @final
509
516
  class Odb:
510
517
  backends: Iterator[OdbBackend]
@@ -24,11 +24,10 @@
24
24
  # Boston, MA 02110-1301, USA.
25
25
 
26
26
  """
27
- This is an special module, it provides stuff used by by pygit2 at run-time.
27
+ This is a special module, it provides stuff used by pygit2 at run-time.
28
28
  """
29
29
 
30
30
  # Import from the Standard Library
31
- import codecs
32
31
  import sys
33
32
  from pathlib import Path
34
33
 
@@ -89,9 +88,8 @@ h_files = [
89
88
  ]
90
89
  h_source = []
91
90
  for h_file in h_files:
92
- h_file = dir_path / 'decl' / h_file # type: ignore
93
- with codecs.open(h_file, 'r', 'utf-8') as f:
94
- h_source.append(f.read())
91
+ h_path = dir_path / 'decl' / h_file
92
+ h_source.append(h_path.read_text(encoding='utf-8'))
95
93
 
96
94
  C_HEADER_SRC = '\n'.join(h_source)
97
95