Skip to content

Commit d0d99b0

Browse files
committed
Merge branch 'git-merge' of https://github.com/rohitsanj/pygit2 into git-merge
2 parents 4f2c909 + 92bff5a commit d0d99b0

File tree

7 files changed

+277
-67
lines changed

7 files changed

+277
-67
lines changed

pygit2/_pygit2.pyi

+5-2
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ GIT_REF_INVALID: int
155155
GIT_REF_LISTALL: int
156156
GIT_REF_OID: int
157157
GIT_REF_SYMBOLIC: int
158+
GIT_REFERENCES_ALL: int
159+
GIT_REFERENCES_BRANCHES: int
160+
GIT_REFERENCES_TAGS: int
158161
GIT_RESET_HARD: int
159162
GIT_RESET_MIXED: int
160163
GIT_RESET_SOFT: int
@@ -475,8 +478,6 @@ class Repository:
475478
def init_submodules(self, submodules: list[Submodule] = None, overwrite = False) -> None: ...
476479
def list_worktrees(self) -> list[str]: ...
477480
def listall_branches(self, flag: int = GIT_BRANCH_LOCAL) -> list[str]: ...
478-
def listall_reference_objects(self) -> list[Reference]: ...
479-
def listall_references(self) -> list[str]: ...
480481
def listall_stashes(self) -> list[Stash]: ...
481482
def listall_submodules(self) -> list[str]: ...
482483
def lookup_branch(self, branch_name: str, branch_type: int = GIT_BRANCH_LOCAL) -> Branch: ...
@@ -492,6 +493,8 @@ class Repository:
492493
def path_is_ignored(self, path: str) -> bool: ...
493494
def raw_listall_branches(self, flag: int = GIT_BRANCH_LOCAL) -> list[bytes]: ...
494495
def raw_listall_references(self) -> list[bytes]: ...
496+
def references_iterator_init(self) -> Iterator[Reference]: ...
497+
def references_iterator_next(self, iter: Iterator, references_return_type: int) -> Reference: ...
495498
def reset(self, oid: _OidArg, reset_type: int) -> None: ...
496499
def revparse(self, revspec: str) -> RevSpec: ...
497500
def revparse_ext(self, revision: str) -> tuple[Object,Reference]: ...

pygit2/repository.py

+50-4
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,17 @@
2828
from string import hexdigits
2929
import tarfile
3030
from time import time
31+
import typing
3132
import warnings
3233

3334
# Import from pygit2
3435
from ._pygit2 import Repository as _Repository, init_file_backend
3536
from ._pygit2 import Oid, GIT_OID_HEXSZ, GIT_OID_MINPREFIXLEN
36-
from ._pygit2 import GIT_CHECKOUT_SAFE, GIT_CHECKOUT_RECREATE_MISSING, GIT_DIFF_NORMAL
37+
from ._pygit2 import GIT_DIFF_NORMAL
3738
from ._pygit2 import GIT_FILEMODE_LINK
3839
from ._pygit2 import GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE, GIT_BRANCH_ALL
3940
from ._pygit2 import GIT_REF_SYMBOLIC
41+
from ._pygit2 import GIT_REFERENCES_ALL, GIT_REFERENCES_BRANCHES, GIT_REFERENCES_TAGS
4042
from ._pygit2 import Reference, Tree, Commit, Blob, Signature
4143
from ._pygit2 import InvalidSpecError
4244

@@ -47,7 +49,7 @@
4749
from .index import Index
4850
from .remote import RemoteCollection
4951
from .blame import Blame
50-
from .utils import to_bytes, StrArray
52+
from .utils import to_bytes
5153
from .submodule import Submodule
5254
from .packbuilder import PackBuilder
5355

@@ -291,6 +293,16 @@ def create_reference(self, name, target, force=False, message=None):
291293
return self.create_reference_symbolic(name, target, force,
292294
message=message)
293295

296+
def listall_references(self) -> typing.List[str]:
297+
"""Return a list with all the references in the repository.
298+
"""
299+
return list(x.name for x in self.references.iterator())
300+
301+
def listall_reference_objects(self) -> typing.List[Reference]:
302+
"""Return a list with all the reference objects in the repository.
303+
"""
304+
return list(x for x in self.references.iterator())
305+
294306
def resolve_refish(self, refish):
295307
"""Convert a reference-like short name "ref-ish" to a valid
296308
(commit, reference) pair.
@@ -1624,8 +1636,42 @@ def get(self, key: str):
16241636
return None
16251637

16261638
def __iter__(self):
1627-
for ref_name in self._repository.listall_references():
1628-
yield ref_name
1639+
iter = self._repository.references_iterator_init()
1640+
while True:
1641+
ref = self._repository.references_iterator_next(iter)
1642+
if ref:
1643+
yield ref.name
1644+
else:
1645+
return
1646+
1647+
def iterator(self, references_return_type:int = GIT_REFERENCES_ALL):
1648+
""" Creates a new iterator and fetches references for a given repository.
1649+
1650+
Can also filter and pass all refs or only branches or only tags.
1651+
1652+
Parameters:
1653+
1654+
references_return_type: int
1655+
Optional specifier to filter references. By default, all references are
1656+
returned.
1657+
1658+
The following values are accepted:
1659+
0 -> GIT_REFERENCES_ALL, fetches all refs, this is the default
1660+
1 -> GIT_REFERENCES_BRANCHES, fetches only branches
1661+
2 -> GIT_REFERENCES_TAGS, fetches only tags
1662+
1663+
TODO: Add support for filtering by reference types notes and remotes.
1664+
"""
1665+
1666+
if references_return_type not in (GIT_REFERENCES_ALL, GIT_REFERENCES_BRANCHES, GIT_REFERENCES_TAGS):
1667+
raise ValueError("Parameter references_return_type is invalid")
1668+
iter = self._repository.references_iterator_init()
1669+
while True:
1670+
ref = self._repository.references_iterator_next(iter, references_return_type)
1671+
if ref:
1672+
yield ref
1673+
else:
1674+
return
16291675

16301676
def create(self, name, target, force=False):
16311677
return self._repository.create_reference(name, target, force)

src/pygit2.c

+5
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ extern PyTypeObject NoteIterType;
7979
extern PyTypeObject WorktreeType;
8080
extern PyTypeObject MailmapType;
8181
extern PyTypeObject StashType;
82+
extern PyTypeObject RefsIteratorType;
8283

8384

8485
PyDoc_STRVAR(discover_repository__doc__,
@@ -371,6 +372,7 @@ PyInit__pygit2(void)
371372
INIT_TYPE(TreeBuilderType, NULL, NULL)
372373
INIT_TYPE(BlobType, &ObjectType, NULL)
373374
INIT_TYPE(TagType, &ObjectType, NULL)
375+
INIT_TYPE(RefsIteratorType, NULL, NULL)
374376
ADD_TYPE(m, Object)
375377
ADD_TYPE(m, Commit)
376378
ADD_TYPE(m, Signature)
@@ -431,6 +433,9 @@ PyInit__pygit2(void)
431433
ADD_CONSTANT_INT(m, GIT_REF_OID)
432434
ADD_CONSTANT_INT(m, GIT_REF_SYMBOLIC)
433435
ADD_CONSTANT_INT(m, GIT_REF_LISTALL)
436+
ADD_CONSTANT_INT(m, GIT_REFERENCES_ALL)
437+
ADD_CONSTANT_INT(m, GIT_REFERENCES_BRANCHES)
438+
ADD_CONSTANT_INT(m, GIT_REFERENCES_TAGS)
434439

435440
/*
436441
* RevSpec

0 commit comments

Comments
 (0)