pygit2 1.18.2__tar.gz → 1.19.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 (197) hide show
  1. {pygit2-1.18.2 → pygit2-1.19.0}/AUTHORS.md +4 -3
  2. {pygit2-1.18.2 → pygit2-1.19.0}/CHANGELOG.md +68 -25
  3. {pygit2-1.18.2 → pygit2-1.19.0}/PKG-INFO +17 -13
  4. {pygit2-1.18.2 → pygit2-1.19.0}/README.md +13 -9
  5. pygit2-1.19.0/build.ps1 +21 -0
  6. {pygit2-1.18.2 → pygit2-1.19.0}/build.sh +1 -1
  7. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/__init__.py +3 -0
  8. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/_build.py +1 -1
  9. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/_libgit2/ffi.pyi +5 -0
  10. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/_run.py +1 -0
  11. pygit2-1.19.0/pygit2/decl/transaction.h +8 -0
  12. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/types.h +2 -0
  13. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/index.py +1 -7
  14. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/repository.py +18 -0
  15. pygit2-1.19.0/pygit2/transaction.py +199 -0
  16. pygit2-1.19.0/pyproject.toml +76 -0
  17. {pygit2-1.18.2 → pygit2-1.19.0}/requirements.txt +1 -1
  18. {pygit2-1.18.2 → pygit2-1.19.0}/setup.py +5 -5
  19. {pygit2-1.18.2 → pygit2-1.19.0}/src/pygit2.c +4 -0
  20. {pygit2-1.18.2 → pygit2-1.19.0}/src/repository.c +23 -3
  21. {pygit2-1.18.2 → pygit2-1.19.0}/test/__init__.py +3 -2
  22. {pygit2-1.18.2 → pygit2-1.19.0}/test/conftest.py +0 -5
  23. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_refs.py +4 -1
  24. pygit2-1.19.0/test/test_transaction.py +327 -0
  25. pygit2-1.18.2/pyproject.toml +0 -42
  26. {pygit2-1.18.2 → pygit2-1.19.0}/COPYING +0 -0
  27. {pygit2-1.18.2 → pygit2-1.19.0}/Makefile +0 -0
  28. {pygit2-1.18.2 → pygit2-1.19.0}/SPONSORS.md +0 -0
  29. {pygit2-1.18.2 → pygit2-1.19.0}/build_tag.py +0 -0
  30. {pygit2-1.18.2 → pygit2-1.19.0}/mypy-stubtest.ini +0 -0
  31. {pygit2-1.18.2 → pygit2-1.19.0}/mypy.ini +0 -0
  32. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/_pygit2.pyi +0 -0
  33. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/blame.py +0 -0
  34. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/blob.py +0 -0
  35. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/branches.py +0 -0
  36. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/callbacks.py +0 -0
  37. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/config.py +0 -0
  38. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/credentials.py +0 -0
  39. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/attr.h +0 -0
  40. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/blame.h +0 -0
  41. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/buffer.h +0 -0
  42. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/callbacks.h +0 -0
  43. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/checkout.h +0 -0
  44. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/clone.h +0 -0
  45. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/commit.h +0 -0
  46. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/common.h +0 -0
  47. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/config.h +0 -0
  48. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/describe.h +0 -0
  49. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/diff.h +0 -0
  50. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/errors.h +0 -0
  51. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/graph.h +0 -0
  52. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/index.h +0 -0
  53. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/indexer.h +0 -0
  54. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/merge.h +0 -0
  55. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/net.h +0 -0
  56. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/oid.h +0 -0
  57. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/options.h +0 -0
  58. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/pack.h +0 -0
  59. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/proxy.h +0 -0
  60. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/refspec.h +0 -0
  61. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/remote.h +0 -0
  62. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/repository.h +0 -0
  63. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/revert.h +0 -0
  64. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/stash.h +0 -0
  65. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/strarray.h +0 -0
  66. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/submodule.h +0 -0
  67. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/decl/transport.h +0 -0
  68. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/enums.py +0 -0
  69. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/errors.py +0 -0
  70. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/ffi.py +0 -0
  71. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/filter.py +0 -0
  72. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/legacyenums.py +0 -0
  73. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/options.py +0 -0
  74. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/packbuilder.py +0 -0
  75. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/py.typed +0 -0
  76. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/references.py +0 -0
  77. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/refspec.py +0 -0
  78. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/remotes.py +0 -0
  79. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/settings.py +0 -0
  80. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/submodules.py +0 -0
  81. {pygit2-1.18.2 → pygit2-1.19.0}/pygit2/utils.py +0 -0
  82. {pygit2-1.18.2 → pygit2-1.19.0}/pytest.ini +0 -0
  83. {pygit2-1.18.2 → pygit2-1.19.0}/requirements-test.txt +0 -0
  84. {pygit2-1.18.2 → pygit2-1.19.0}/setup.cfg +0 -0
  85. {pygit2-1.18.2 → pygit2-1.19.0}/src/blob.c +0 -0
  86. {pygit2-1.18.2 → pygit2-1.19.0}/src/branch.c +0 -0
  87. {pygit2-1.18.2 → pygit2-1.19.0}/src/branch.h +0 -0
  88. {pygit2-1.18.2 → pygit2-1.19.0}/src/commit.c +0 -0
  89. {pygit2-1.18.2 → pygit2-1.19.0}/src/diff.c +0 -0
  90. {pygit2-1.18.2 → pygit2-1.19.0}/src/diff.h +0 -0
  91. {pygit2-1.18.2 → pygit2-1.19.0}/src/error.c +0 -0
  92. {pygit2-1.18.2 → pygit2-1.19.0}/src/error.h +0 -0
  93. {pygit2-1.18.2 → pygit2-1.19.0}/src/filter.c +0 -0
  94. {pygit2-1.18.2 → pygit2-1.19.0}/src/filter.h +0 -0
  95. {pygit2-1.18.2 → pygit2-1.19.0}/src/mailmap.c +0 -0
  96. {pygit2-1.18.2 → pygit2-1.19.0}/src/mailmap.h +0 -0
  97. {pygit2-1.18.2 → pygit2-1.19.0}/src/note.c +0 -0
  98. {pygit2-1.18.2 → pygit2-1.19.0}/src/note.h +0 -0
  99. {pygit2-1.18.2 → pygit2-1.19.0}/src/object.c +0 -0
  100. {pygit2-1.18.2 → pygit2-1.19.0}/src/object.h +0 -0
  101. {pygit2-1.18.2 → pygit2-1.19.0}/src/odb.c +0 -0
  102. {pygit2-1.18.2 → pygit2-1.19.0}/src/odb.h +0 -0
  103. {pygit2-1.18.2 → pygit2-1.19.0}/src/odb_backend.c +0 -0
  104. {pygit2-1.18.2 → pygit2-1.19.0}/src/odb_backend.h +0 -0
  105. {pygit2-1.18.2 → pygit2-1.19.0}/src/oid.c +0 -0
  106. {pygit2-1.18.2 → pygit2-1.19.0}/src/oid.h +0 -0
  107. {pygit2-1.18.2 → pygit2-1.19.0}/src/patch.c +0 -0
  108. {pygit2-1.18.2 → pygit2-1.19.0}/src/patch.h +0 -0
  109. {pygit2-1.18.2 → pygit2-1.19.0}/src/refdb.c +0 -0
  110. {pygit2-1.18.2 → pygit2-1.19.0}/src/refdb.h +0 -0
  111. {pygit2-1.18.2 → pygit2-1.19.0}/src/refdb_backend.c +0 -0
  112. {pygit2-1.18.2 → pygit2-1.19.0}/src/refdb_backend.h +0 -0
  113. {pygit2-1.18.2 → pygit2-1.19.0}/src/reference.c +0 -0
  114. {pygit2-1.18.2 → pygit2-1.19.0}/src/reference.h +0 -0
  115. {pygit2-1.18.2 → pygit2-1.19.0}/src/repository.h +0 -0
  116. {pygit2-1.18.2 → pygit2-1.19.0}/src/revspec.c +0 -0
  117. {pygit2-1.18.2 → pygit2-1.19.0}/src/revspec.h +0 -0
  118. {pygit2-1.18.2 → pygit2-1.19.0}/src/signature.c +0 -0
  119. {pygit2-1.18.2 → pygit2-1.19.0}/src/signature.h +0 -0
  120. {pygit2-1.18.2 → pygit2-1.19.0}/src/stash.c +0 -0
  121. {pygit2-1.18.2 → pygit2-1.19.0}/src/tag.c +0 -0
  122. {pygit2-1.18.2 → pygit2-1.19.0}/src/tree.c +0 -0
  123. {pygit2-1.18.2 → pygit2-1.19.0}/src/tree.h +0 -0
  124. {pygit2-1.18.2 → pygit2-1.19.0}/src/treebuilder.c +0 -0
  125. {pygit2-1.18.2 → pygit2-1.19.0}/src/treebuilder.h +0 -0
  126. {pygit2-1.18.2 → pygit2-1.19.0}/src/types.h +0 -0
  127. {pygit2-1.18.2 → pygit2-1.19.0}/src/utils.c +0 -0
  128. {pygit2-1.18.2 → pygit2-1.19.0}/src/utils.h +0 -0
  129. {pygit2-1.18.2 → pygit2-1.19.0}/src/walker.c +0 -0
  130. {pygit2-1.18.2 → pygit2-1.19.0}/src/walker.h +0 -0
  131. {pygit2-1.18.2 → pygit2-1.19.0}/src/wildmatch.c +0 -0
  132. {pygit2-1.18.2 → pygit2-1.19.0}/src/wildmatch.h +0 -0
  133. {pygit2-1.18.2 → pygit2-1.19.0}/src/worktree.c +0 -0
  134. {pygit2-1.18.2 → pygit2-1.19.0}/src/worktree.h +0 -0
  135. {pygit2-1.18.2 → pygit2-1.19.0}/test/data/barerepo.zip +0 -0
  136. {pygit2-1.18.2 → pygit2-1.19.0}/test/data/binaryfilerepo.zip +0 -0
  137. {pygit2-1.18.2 → pygit2-1.19.0}/test/data/blameflagsrepo.zip +0 -0
  138. {pygit2-1.18.2 → pygit2-1.19.0}/test/data/dirtyrepo.zip +0 -0
  139. {pygit2-1.18.2 → pygit2-1.19.0}/test/data/emptyrepo.zip +0 -0
  140. {pygit2-1.18.2 → pygit2-1.19.0}/test/data/encoding.zip +0 -0
  141. {pygit2-1.18.2 → pygit2-1.19.0}/test/data/gpgsigned.zip +0 -0
  142. {pygit2-1.18.2 → pygit2-1.19.0}/test/data/submodulerepo.zip +0 -0
  143. {pygit2-1.18.2 → pygit2-1.19.0}/test/data/testrepo.zip +0 -0
  144. {pygit2-1.18.2 → pygit2-1.19.0}/test/data/testrepoformerging.zip +0 -0
  145. {pygit2-1.18.2 → pygit2-1.19.0}/test/data/testrepopacked.zip +0 -0
  146. {pygit2-1.18.2 → pygit2-1.19.0}/test/data/trailerrepo.zip +0 -0
  147. {pygit2-1.18.2 → pygit2-1.19.0}/test/data/utf8branchrepo.zip +0 -0
  148. {pygit2-1.18.2 → pygit2-1.19.0}/test/keys/pygit2_empty +0 -0
  149. {pygit2-1.18.2 → pygit2-1.19.0}/test/keys/pygit2_empty.pub +0 -0
  150. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_apply_diff.py +0 -0
  151. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_archive.py +0 -0
  152. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_attributes.py +0 -0
  153. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_blame.py +0 -0
  154. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_blob.py +0 -0
  155. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_branch.py +0 -0
  156. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_branch_empty.py +0 -0
  157. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_cherrypick.py +0 -0
  158. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_commit.py +0 -0
  159. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_commit_gpg.py +0 -0
  160. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_commit_trailer.py +0 -0
  161. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_config.py +0 -0
  162. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_credentials.py +0 -0
  163. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_describe.py +0 -0
  164. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_diff.py +0 -0
  165. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_diff_binary.py +0 -0
  166. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_filter.py +0 -0
  167. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_index.py +0 -0
  168. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_mailmap.py +0 -0
  169. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_merge.py +0 -0
  170. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_nonunicode.py +0 -0
  171. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_note.py +0 -0
  172. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_object.py +0 -0
  173. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_odb.py +0 -0
  174. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_odb_backend.py +0 -0
  175. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_oid.py +0 -0
  176. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_options.py +0 -0
  177. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_packbuilder.py +0 -0
  178. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_patch.py +0 -0
  179. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_patch_encoding.py +0 -0
  180. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_refdb_backend.py +0 -0
  181. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_remote.py +0 -0
  182. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_remote_prune.py +0 -0
  183. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_remote_utf8.py +0 -0
  184. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_repository.py +0 -0
  185. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_repository_bare.py +0 -0
  186. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_repository_custom.py +0 -0
  187. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_repository_empty.py +0 -0
  188. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_revparse.py +0 -0
  189. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_revwalk.py +0 -0
  190. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_settings.py +0 -0
  191. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_signature.py +0 -0
  192. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_status.py +0 -0
  193. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_submodule.py +0 -0
  194. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_tag.py +0 -0
  195. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_tree.py +0 -0
  196. {pygit2-1.18.2 → pygit2-1.19.0}/test/test_treebuilder.py +0 -0
  197. {pygit2-1.18.2 → pygit2-1.19.0}/test/utils.py +0 -0
@@ -15,6 +15,7 @@ Authors:
15
15
  Daniel Rodríguez Troitiño
16
16
  Peter Rowlands
17
17
  Richo Healey
18
+ Brendan Doherty
18
19
  Christian Boos
19
20
  Julien Miotte
20
21
  Nick Hynes
@@ -50,7 +51,7 @@ Authors:
50
51
  Mathieu Parent
51
52
  Michał Kępień
52
53
  Nicolas Dandrimont
53
- Raphael Medaer (Escaux)
54
+ Raphael Medaer
54
55
  Yaroslav Halchenko
55
56
  Anatoly Techtonik
56
57
  Andrew Olsen
@@ -64,6 +65,7 @@ Authors:
64
65
  Santiago Perez De Rosso
65
66
  Sebastian Thiel
66
67
  Thom Wiggers
68
+ WANG Xuerui
67
69
  William Manley
68
70
  Alexander Linne
69
71
  Alok Singhal
@@ -89,7 +91,6 @@ Authors:
89
91
  Sukhman Bhuller
90
92
  Thomas Kluyver
91
93
  Tyler Cipriani
92
- WANG Xuerui
93
94
  Alex Chamberlain
94
95
  Alexander Bayandin
95
96
  Amit Bakshi
@@ -98,6 +99,7 @@ Authors:
98
99
  Ben Davis
99
100
  CJ Steiner
100
101
  Colin Watson
102
+ Craig de Stigter
101
103
  Dan Yeaw
102
104
  Dustin Raimondi
103
105
  Eric Schrijver
@@ -156,7 +158,6 @@ Authors:
156
158
  Chris Rebert
157
159
  Christopher Hunt
158
160
  Claudio Jolowicz
159
- Craig de Stigter
160
161
  Cristian Hotea
161
162
  Cyril Jouve
162
163
  Dan Cecile
@@ -1,3 +1,38 @@
1
+ # 1.19.0 (2025-10-23)
2
+
3
+ - Add support for Python 3.14 and drop 3.10
4
+
5
+ - Support threaded builds (experimental)
6
+ [#1430](https://github.com/libgit2/pygit2/pull/1430)
7
+ [#1435](https://github.com/libgit2/pygit2/pull/1435)
8
+
9
+ - Add Linux musl wheels for AArch64
10
+
11
+ - Add Windows wheels for AArch64;
12
+ CI: build Windows wheels with cibuildwheel on GitHub
13
+ [#1423](https://github.com/libgit2/pygit2/pull/1423)
14
+
15
+ - New `Repository.transaction()` context manager, returns new `ReferenceTransaction`
16
+ [#1420](https://github.com/libgit2/pygit2/pull/1420)
17
+
18
+ - CI: add GitHub releases and other improvements
19
+ [#1433](https://github.com/libgit2/pygit2/pull/1433)
20
+ [#1432](https://github.com/libgit2/pygit2/pull/1432)
21
+ [#1425](https://github.com/libgit2/pygit2/pull/1425)
22
+ [#1431](https://github.com/libgit2/pygit2/pull/1431)
23
+
24
+ - Documentation improvements and other changes
25
+ [#1426](https://github.com/libgit2/pygit2/pull/1426)
26
+ [#1424](https://github.com/libgit2/pygit2/pull/1424)
27
+
28
+ Breaking changes:
29
+
30
+ - Remove deprecated `IndexEntry.hex`, use `str(entry.id)` instead of `entry.hex`
31
+
32
+ Deprecations:
33
+
34
+ - Deprecate `IndexEntry.oid`, use `entry.id` instead of `entry.oid`
35
+
1
36
  # 1.18.2 (2025-08-16)
2
37
 
3
38
  - Add support for almost all global options
@@ -298,31 +333,39 @@ Deprecations:
298
333
 
299
334
  # 1.14.0 (2024-01-26)
300
335
 
301
- - Drop support for Python 3.8
302
- - Add Linux wheels for musl on x86\_64
303
- [#1266](https://github.com/libgit2/pygit2/pull/1266)
304
- - New `Repository.submodules` namespace
305
- [#1250](https://github.com/libgit2/pygit2/pull/1250)
306
- - New `Repository.listall_mergeheads()`, `Repository.message`,
307
- `Repository.raw_message` and `Repository.remove_message()`
308
- [#1261](https://github.com/libgit2/pygit2/pull/1261)
309
- - New `pygit2.enums` supersedes the `GIT_` constants
310
- [#1251](https://github.com/libgit2/pygit2/pull/1251)
311
- - Now `Repository.status()`, `Repository.status_file()`,
312
- `Repository.merge_analysis()`, `DiffFile.flags`, `DiffFile.mode`,
313
- `DiffDelta.flags` and `DiffDelta.status` return enums
314
- [#1263](https://github.com/libgit2/pygit2/pull/1263)
315
- - Now repository\'s `merge()`, `merge_commits()` and `merge_trees()`
316
- take enums/flags for their `favor`, `flags` and `file_flags` arguments.
317
- [#1271](https://github.com/libgit2/pygit2/pull/1271)
318
- [#1272](https://github.com/libgit2/pygit2/pull/1272)
319
- - Fix crash in filter cleanup
320
- [#1259](https://github.com/libgit2/pygit2/pull/1259)
321
- - Documentation fixes
322
- [#1255](https://github.com/libgit2/pygit2/pull/1255)
323
- [#1258](https://github.com/libgit2/pygit2/pull/1258)
324
- [#1268](https://github.com/libgit2/pygit2/pull/1268)
325
- [#1270](https://github.com/libgit2/pygit2/pull/1270)
336
+ - Drop support for Python 3.8
337
+
338
+ - Add Linux wheels for musl on x86\_64
339
+ [#1266](https://github.com/libgit2/pygit2/pull/1266)
340
+
341
+ - New `Repository.submodules` namespace
342
+ [#1250](https://github.com/libgit2/pygit2/pull/1250)
343
+
344
+ - New `Repository.listall_mergeheads()`, `Repository.message`,
345
+ `Repository.raw_message` and `Repository.remove_message()`
346
+ [#1261](https://github.com/libgit2/pygit2/pull/1261)
347
+
348
+ - New `pygit2.enums` supersedes the `GIT_` constants
349
+ [#1251](https://github.com/libgit2/pygit2/pull/1251)
350
+
351
+ - Now `Repository.status()`, `Repository.status_file()`,
352
+ `Repository.merge_analysis()`, `DiffFile.flags`, `DiffFile.mode`,
353
+ `DiffDelta.flags` and `DiffDelta.status` return enums
354
+ [#1263](https://github.com/libgit2/pygit2/pull/1263)
355
+
356
+ - Now repository\'s `merge()`, `merge_commits()` and `merge_trees()`
357
+ take enums/flags for their `favor`, `flags` and `file_flags` arguments.
358
+ [#1271](https://github.com/libgit2/pygit2/pull/1271)
359
+ [#1272](https://github.com/libgit2/pygit2/pull/1272)
360
+
361
+ - Fix crash in filter cleanup
362
+ [#1259](https://github.com/libgit2/pygit2/pull/1259)
363
+
364
+ - Documentation fixes
365
+ [#1255](https://github.com/libgit2/pygit2/pull/1255)
366
+ [#1258](https://github.com/libgit2/pygit2/pull/1258)
367
+ [#1268](https://github.com/libgit2/pygit2/pull/1268)
368
+ [#1270](https://github.com/libgit2/pygit2/pull/1270)
326
369
 
327
370
  Breaking changes:
328
371
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pygit2
3
- Version: 1.18.2
3
+ Version: 1.19.0
4
4
  Summary: Python bindings for libgit2.
5
5
  Home-page: https://github.com/libgit2/pygit2
6
6
  Maintainer: J. David Ibáñez
@@ -14,19 +14,19 @@ Classifier: Development Status :: 5 - Production/Stable
14
14
  Classifier: Intended Audience :: Developers
15
15
  Classifier: Programming Language :: Python
16
16
  Classifier: Programming Language :: Python :: 3
17
- Classifier: Programming Language :: Python :: 3.10
18
17
  Classifier: Programming Language :: Python :: 3.11
19
18
  Classifier: Programming Language :: Python :: 3.12
20
19
  Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
21
  Classifier: Programming Language :: Python :: Implementation :: PyPy
22
22
  Classifier: Programming Language :: Python :: Implementation :: CPython
23
23
  Classifier: Topic :: Software Development :: Version Control
24
24
  Classifier: Typing :: Typed
25
- Requires-Python: >=3.10
25
+ Requires-Python: >=3.11
26
26
  Description-Content-Type: text/markdown
27
27
  License-File: COPYING
28
28
  License-File: AUTHORS.md
29
- Requires-Dist: cffi>=1.17.0
29
+ Requires-Dist: cffi>=2.0
30
30
  Dynamic: classifier
31
31
  Dynamic: description
32
32
  Dynamic: description-content-type
@@ -44,20 +44,24 @@ Dynamic: summary
44
44
  # pygit2 - libgit2 bindings in Python
45
45
 
46
46
  Bindings to the libgit2 shared library, implements Git plumbing.
47
- Supports Python 3.10 to 3.13 and PyPy3 7.3+
47
+ Supports Python 3.11 to 3.14 and PyPy3 7.3+
48
48
 
49
- [![image](https://github.com/libgit2/pygit2/actions/workflows/tests.yml/badge.svg)](https://github.com/libgit2/pygit2/actions/workflows/tests.yml)
49
+ [![test-ci-badge][test-ci-badge]][test-ci-link]
50
+ [![deploy-ci-badge][deploy-ci-badge]][deploy-ci-link]
50
51
 
51
- [![image](https://ci.appveyor.com/api/projects/status/edmwc0dctk5nacx0/branch/master?svg=true)](https://ci.appveyor.com/project/jdavid/pygit2/branch/master)
52
+ [deploy-ci-badge]: https://github.com/libgit2/pygit2/actions/workflows/wheels.yml/badge.svg
53
+ [deploy-ci-link]: https://github.com/libgit2/pygit2/actions/workflows/wheels.yml
54
+ [test-ci-badge]: https://github.com/libgit2/pygit2/actions/workflows/tests.yml/badge.svg
55
+ [test-ci-link]: https://github.com/libgit2/pygit2/actions/workflows/tests.yml
52
56
 
53
57
  ## Links
54
58
 
55
- - Documentation - <https://www.pygit2.org/>
56
- - Install - <https://www.pygit2.org/install.html>
57
- - Download - <https://pypi.org/project/pygit2/>
58
- - Source code and issue tracker - <https://github.com/libgit2/pygit2>
59
- - Changelog - <https://github.com/libgit2/pygit2/blob/master/CHANGELOG.md>
60
- - Authors - <https://github.com/libgit2/pygit2/blob/master/AUTHORS.md>
59
+ - Documentation - <https://www.pygit2.org/>
60
+ - Install - <https://www.pygit2.org/install.html>
61
+ - Download - <https://pypi.org/project/pygit2/>
62
+ - Source code and issue tracker - <https://github.com/libgit2/pygit2>
63
+ - Changelog - <https://github.com/libgit2/pygit2/blob/master/CHANGELOG.md>
64
+ - Authors - <https://github.com/libgit2/pygit2/blob/master/AUTHORS.md>
61
65
 
62
66
  ## Sponsors
63
67
 
@@ -1,20 +1,24 @@
1
1
  # pygit2 - libgit2 bindings in Python
2
2
 
3
3
  Bindings to the libgit2 shared library, implements Git plumbing.
4
- Supports Python 3.10 to 3.13 and PyPy3 7.3+
4
+ Supports Python 3.11 to 3.14 and PyPy3 7.3+
5
5
 
6
- [![image](https://github.com/libgit2/pygit2/actions/workflows/tests.yml/badge.svg)](https://github.com/libgit2/pygit2/actions/workflows/tests.yml)
6
+ [![test-ci-badge][test-ci-badge]][test-ci-link]
7
+ [![deploy-ci-badge][deploy-ci-badge]][deploy-ci-link]
7
8
 
8
- [![image](https://ci.appveyor.com/api/projects/status/edmwc0dctk5nacx0/branch/master?svg=true)](https://ci.appveyor.com/project/jdavid/pygit2/branch/master)
9
+ [deploy-ci-badge]: https://github.com/libgit2/pygit2/actions/workflows/wheels.yml/badge.svg
10
+ [deploy-ci-link]: https://github.com/libgit2/pygit2/actions/workflows/wheels.yml
11
+ [test-ci-badge]: https://github.com/libgit2/pygit2/actions/workflows/tests.yml/badge.svg
12
+ [test-ci-link]: https://github.com/libgit2/pygit2/actions/workflows/tests.yml
9
13
 
10
14
  ## Links
11
15
 
12
- - Documentation - <https://www.pygit2.org/>
13
- - Install - <https://www.pygit2.org/install.html>
14
- - Download - <https://pypi.org/project/pygit2/>
15
- - Source code and issue tracker - <https://github.com/libgit2/pygit2>
16
- - Changelog - <https://github.com/libgit2/pygit2/blob/master/CHANGELOG.md>
17
- - Authors - <https://github.com/libgit2/pygit2/blob/master/AUTHORS.md>
16
+ - Documentation - <https://www.pygit2.org/>
17
+ - Install - <https://www.pygit2.org/install.html>
18
+ - Download - <https://pypi.org/project/pygit2/>
19
+ - Source code and issue tracker - <https://github.com/libgit2/pygit2>
20
+ - Changelog - <https://github.com/libgit2/pygit2/blob/master/CHANGELOG.md>
21
+ - Authors - <https://github.com/libgit2/pygit2/blob/master/AUTHORS.md>
18
22
 
19
23
  ## Sponsors
20
24
 
@@ -0,0 +1,21 @@
1
+ if (!(Test-Path -Path "build")) {
2
+ # in case the pygit2 package build/ workspace has not been created by cibuildwheel yet
3
+ mkdir build
4
+ }
5
+ if (Test-Path -Path "$env:LIBGIT2_SRC") {
6
+ Set-Location "$env:LIBGIT2_SRC"
7
+ # for local runs, reuse build/libgit_src if it exists
8
+ if (Test-Path -Path build) {
9
+ # purge previous build env (likely for a different arch type)
10
+ Remove-Item -Recurse -Force build
11
+ }
12
+ # ensure we are checked out to the right version
13
+ git fetch --depth=1 --tags
14
+ git checkout "v$env:LIBGIT2_VERSION"
15
+ } else {
16
+ # from a fresh run (like in CI)
17
+ git clone --depth=1 -b "v$env:LIBGIT2_VERSION" https://github.com/libgit2/libgit2.git $env:LIBGIT2_SRC
18
+ Set-Location "$env:LIBGIT2_SRC"
19
+ }
20
+ cmake -B build -S . -DBUILD_TESTS=OFF
21
+ cmake --build build/ --config=Release --target install
@@ -134,7 +134,7 @@ if [ -n "$OPENSSL_VERSION" ]; then
134
134
  # Linux
135
135
  tar xf $FILENAME.tar.gz
136
136
  cd $FILENAME
137
- ./Configure shared --prefix=$PREFIX --libdir=$PREFIX/lib
137
+ ./Configure shared no-apps no-docs no-tests --prefix=$PREFIX --libdir=$PREFIX/lib
138
138
  make
139
139
  make install
140
140
  OPENSSL_PREFIX=$(pwd)
@@ -366,6 +366,7 @@ from .remotes import Remote
366
366
  from .repository import Repository
367
367
  from .settings import Settings
368
368
  from .submodules import Submodule
369
+ from .transaction import ReferenceTransaction
369
370
  from .utils import to_bytes, to_str
370
371
 
371
372
  # Features
@@ -971,6 +972,8 @@ __all__ = (
971
972
  'Settings',
972
973
  'submodules',
973
974
  'Submodule',
975
+ 'transaction',
976
+ 'ReferenceTransaction',
974
977
  'utils',
975
978
  'to_bytes',
976
979
  'to_str',
@@ -34,7 +34,7 @@ from pathlib import Path
34
34
  #
35
35
  # The version number of pygit2
36
36
  #
37
- __version__ = '1.18.2'
37
+ __version__ = '1.19.0'
38
38
 
39
39
 
40
40
  #
@@ -239,12 +239,17 @@ class GitRemoteC:
239
239
  class GitReferenceC:
240
240
  pass
241
241
 
242
+ class GitTransactionC:
243
+ pass
244
+
242
245
  def string(a: char_pointer) -> bytes: ...
243
246
  @overload
244
247
  def new(a: Literal['git_repository **']) -> _Pointer[GitRepositoryC]: ...
245
248
  @overload
246
249
  def new(a: Literal['git_remote **']) -> _Pointer[GitRemoteC]: ...
247
250
  @overload
251
+ def new(a: Literal['git_transaction **']) -> _Pointer[GitTransactionC]: ...
252
+ @overload
248
253
  def new(a: Literal['git_repository_init_options *']) -> GitRepositoryInitOptionsC: ...
249
254
  @overload
250
255
  def new(a: Literal['git_submodule_update_options *']) -> GitSubmoduleUpdateOptionsC: ...
@@ -81,6 +81,7 @@ h_files = [
81
81
  'revert.h',
82
82
  'stash.h',
83
83
  'submodule.h',
84
+ 'transaction.h',
84
85
  'options.h',
85
86
  'callbacks.h', # Bridge from libgit2 to Python
86
87
  ]
@@ -0,0 +1,8 @@
1
+ int git_transaction_new(git_transaction **out, git_repository *repo);
2
+ int git_transaction_lock_ref(git_transaction *tx, const char *refname);
3
+ int git_transaction_set_target(git_transaction *tx, const char *refname, const git_oid *target, const git_signature *sig, const char *msg);
4
+ int git_transaction_set_symbolic_target(git_transaction *tx, const char *refname, const char *target, const git_signature *sig, const char *msg);
5
+ int git_transaction_set_reflog(git_transaction *tx, const char *refname, const git_reflog *reflog);
6
+ int git_transaction_remove(git_transaction *tx, const char *refname);
7
+ int git_transaction_commit(git_transaction *tx);
8
+ void git_transaction_free(git_transaction *tx);
@@ -12,6 +12,8 @@ typedef struct git_submodule git_submodule;
12
12
  typedef struct git_transport git_transport;
13
13
  typedef struct git_tree git_tree;
14
14
  typedef struct git_packbuilder git_packbuilder;
15
+ typedef struct git_transaction git_transaction;
16
+ typedef struct git_reflog git_reflog;
15
17
 
16
18
  typedef int64_t git_off_t;
17
19
  typedef int64_t git_time_t;
@@ -446,15 +446,9 @@ class IndexEntry:
446
446
 
447
447
  @property
448
448
  def oid(self):
449
- # For backwards compatibility
449
+ warnings.warn('Use entry.id', DeprecationWarning)
450
450
  return self.id
451
451
 
452
- @property
453
- def hex(self):
454
- """The id of the referenced object as a hex string"""
455
- warnings.warn('Use str(entry.id)', DeprecationWarning)
456
- return str(self.id)
457
-
458
452
  def __str__(self):
459
453
  return f'<path={self.path} id={self.id} mode={self.mode}>'
460
454
 
@@ -78,6 +78,7 @@ from .packbuilder import PackBuilder
78
78
  from .references import References
79
79
  from .remotes import RemoteCollection
80
80
  from .submodules import SubmoduleCollection
81
+ from .transaction import ReferenceTransaction
81
82
  from .utils import StrArray, to_bytes
82
83
 
83
84
  if TYPE_CHECKING:
@@ -120,6 +121,7 @@ class BaseRepository(_Repository):
120
121
  self.references = References(self)
121
122
  self.remotes = RemoteCollection(self)
122
123
  self.submodules = SubmoduleCollection(self)
124
+ self._active_transaction = None
123
125
 
124
126
  # Get the pointer as the contents of a buffer and store it for
125
127
  # later access
@@ -359,6 +361,22 @@ class BaseRepository(_Repository):
359
361
 
360
362
  return (commit, reference) # type: ignore
361
363
 
364
+ def transaction(self) -> ReferenceTransaction:
365
+ """Create a new reference transaction.
366
+
367
+ Returns a context manager that commits all reference updates atomically
368
+ when the context exits successfully, or performs no updates if an exception
369
+ is raised.
370
+
371
+ Example::
372
+
373
+ with repo.transaction() as txn:
374
+ txn.lock_ref('refs/heads/master')
375
+ txn.set_target('refs/heads/master', new_oid, message='Update')
376
+ """
377
+ txn = ReferenceTransaction(self)
378
+ return txn
379
+
362
380
  #
363
381
  # Checkout
364
382
  #
@@ -0,0 +1,199 @@
1
+ # Copyright 2010-2025 The pygit2 contributors
2
+ #
3
+ # This file is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License, version 2,
5
+ # as published by the Free Software Foundation.
6
+ #
7
+ # In addition to the permissions in the GNU General Public License,
8
+ # the authors give you unlimited permission to link the compiled
9
+ # version of this file into combinations with other programs,
10
+ # and to distribute those combinations without any restriction
11
+ # coming from the use of this file. (The General Public License
12
+ # restrictions do apply in other respects; for example, they cover
13
+ # modification of the file, and distribution when not linked into
14
+ # a combined executable.)
15
+ #
16
+ # This file is distributed in the hope that it will be useful, but
17
+ # WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ # General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU General Public License
22
+ # along with this program; see the file COPYING. If not, write to
23
+ # the Free Software Foundation, 51 Franklin Street, Fifth Floor,
24
+ # Boston, MA 02110-1301, USA.
25
+
26
+ from __future__ import annotations
27
+
28
+ import threading
29
+ from typing import TYPE_CHECKING
30
+
31
+ from .errors import check_error
32
+ from .ffi import C, ffi
33
+ from .utils import to_bytes
34
+
35
+ if TYPE_CHECKING:
36
+ from ._pygit2 import Oid, Signature
37
+ from .repository import BaseRepository
38
+
39
+
40
+ class ReferenceTransaction:
41
+ """Context manager for transactional reference updates.
42
+
43
+ A transaction allows multiple reference updates to be performed atomically.
44
+ All updates are applied when the transaction is committed, or none are applied
45
+ if the transaction is rolled back.
46
+
47
+ Example:
48
+ with repo.transaction() as txn:
49
+ txn.lock_ref('refs/heads/master')
50
+ txn.set_target('refs/heads/master', new_oid, message='Update master')
51
+ # Changes committed automatically on context exit
52
+ """
53
+
54
+ def __init__(self, repository: BaseRepository) -> None:
55
+ self._repository = repository
56
+ self._transaction = ffi.new('git_transaction **')
57
+ self._tx = None
58
+ self._thread_id = threading.get_ident()
59
+
60
+ err = C.git_transaction_new(self._transaction, repository._repo)
61
+ check_error(err)
62
+ self._tx = self._transaction[0]
63
+
64
+ def _check_thread(self) -> None:
65
+ """Verify transaction is being used from the same thread that created it."""
66
+ current_thread = threading.get_ident()
67
+ if current_thread != self._thread_id:
68
+ raise RuntimeError(
69
+ f'Transaction created in thread {self._thread_id} '
70
+ f'but used in thread {current_thread}. '
71
+ 'Transactions must be used from the thread that created them.'
72
+ )
73
+
74
+ def lock_ref(self, refname: str) -> None:
75
+ """Lock a reference in preparation for updating it.
76
+
77
+ Args:
78
+ refname: Name of the reference to lock (e.g., 'refs/heads/master')
79
+ """
80
+ self._check_thread()
81
+ if self._tx is None:
82
+ raise ValueError('Transaction already closed')
83
+
84
+ c_refname = ffi.new('char[]', to_bytes(refname))
85
+ err = C.git_transaction_lock_ref(self._tx, c_refname)
86
+ check_error(err)
87
+
88
+ def set_target(
89
+ self,
90
+ refname: str,
91
+ target: Oid | str,
92
+ signature: Signature | None = None,
93
+ message: str | None = None,
94
+ ) -> None:
95
+ """Set the target of a direct reference.
96
+
97
+ The reference must be locked first via lock_ref().
98
+
99
+ Args:
100
+ refname: Name of the reference to update
101
+ target: Target OID or hex string
102
+ signature: Signature for the reflog (None to use repo identity)
103
+ message: Message for the reflog
104
+ """
105
+ self._check_thread()
106
+ if self._tx is None:
107
+ raise ValueError('Transaction already closed')
108
+
109
+ from ._pygit2 import Oid
110
+
111
+ c_refname = ffi.new('char[]', to_bytes(refname))
112
+
113
+ # Convert target to OID
114
+ if isinstance(target, str):
115
+ target = Oid(hex=target)
116
+
117
+ c_oid = ffi.new('git_oid *')
118
+ ffi.buffer(c_oid)[:] = target.raw
119
+
120
+ c_sig = signature._pointer if signature else ffi.NULL
121
+ c_msg = ffi.new('char[]', to_bytes(message)) if message else ffi.NULL
122
+
123
+ err = C.git_transaction_set_target(self._tx, c_refname, c_oid, c_sig, c_msg)
124
+ check_error(err)
125
+
126
+ def set_symbolic_target(
127
+ self,
128
+ refname: str,
129
+ target: str,
130
+ signature: Signature | None = None,
131
+ message: str | None = None,
132
+ ) -> None:
133
+ """Set the target of a symbolic reference.
134
+
135
+ The reference must be locked first via lock_ref().
136
+
137
+ Args:
138
+ refname: Name of the reference to update
139
+ target: Target reference name (e.g., 'refs/heads/master')
140
+ signature: Signature for the reflog (None to use repo identity)
141
+ message: Message for the reflog
142
+ """
143
+ self._check_thread()
144
+ if self._tx is None:
145
+ raise ValueError('Transaction already closed')
146
+
147
+ c_refname = ffi.new('char[]', to_bytes(refname))
148
+ c_target = ffi.new('char[]', to_bytes(target))
149
+ c_sig = signature._pointer if signature else ffi.NULL
150
+ c_msg = ffi.new('char[]', to_bytes(message)) if message else ffi.NULL
151
+
152
+ err = C.git_transaction_set_symbolic_target(
153
+ self._tx, c_refname, c_target, c_sig, c_msg
154
+ )
155
+ check_error(err)
156
+
157
+ def remove(self, refname: str) -> None:
158
+ """Remove a reference.
159
+
160
+ The reference must be locked first via lock_ref().
161
+
162
+ Args:
163
+ refname: Name of the reference to remove
164
+ """
165
+ self._check_thread()
166
+ if self._tx is None:
167
+ raise ValueError('Transaction already closed')
168
+
169
+ c_refname = ffi.new('char[]', to_bytes(refname))
170
+ err = C.git_transaction_remove(self._tx, c_refname)
171
+ check_error(err)
172
+
173
+ def commit(self) -> None:
174
+ """Commit the transaction, applying all queued updates."""
175
+ self._check_thread()
176
+ if self._tx is None:
177
+ raise ValueError('Transaction already closed')
178
+
179
+ err = C.git_transaction_commit(self._tx)
180
+ check_error(err)
181
+
182
+ def __enter__(self) -> ReferenceTransaction:
183
+ return self
184
+
185
+ def __exit__(self, exc_type, exc_val, exc_tb) -> None:
186
+ self._check_thread()
187
+ # Only commit if no exception occurred
188
+ if exc_type is None and self._tx is not None:
189
+ self.commit()
190
+
191
+ # Always free the transaction
192
+ if self._tx is not None:
193
+ C.git_transaction_free(self._tx)
194
+ self._tx = None
195
+
196
+ def __del__(self) -> None:
197
+ if self._tx is not None:
198
+ C.git_transaction_free(self._tx)
199
+ self._tx = None