Skip to content

Commit ea5b51b

Browse files
committed
fix(repository): dereference reflog identity correctly
Since its introduction in commit 81520c9 (Update to libgit2 v0.23), the reflog identity getter (Repository.ident) has been passing the (char **) variables directly to ffi.string() as C-strings, when they really are pointers to C-strings. Fix by dereferencing the pointer to a C-string first. Furthermore, Repository.ident assumes that libgit2 holds a valid C-string, when the reflog identity is initialized to NULL, and can be explicitly set to such with `set_ident (None, None)`. So map None to ffi.NULL (which maybe_string() happens to already do, so I simply delegated to that...). I also added a few regression tests to ensure neither issue shows up again. Signed-off-by: Ethan Meng <ethan@rapidcow.org>
1 parent 7fd5bfd commit ea5b51b

2 files changed

Lines changed: 15 additions & 2 deletions

File tree

pygit2/repository.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
from .remotes import RemoteCollection
8282
from .submodules import SubmoduleCollection
8383
from .transaction import ReferenceTransaction
84-
from .utils import StrArray, to_bytes
84+
from .utils import StrArray, maybe_string, to_bytes
8585

8686
if TYPE_CHECKING:
8787
from pygit2._libgit2.ffi import (
@@ -1585,7 +1585,7 @@ def ident(self):
15851585
err = C.git_repository_ident(cname, cemail, self._repo)
15861586
check_error(err)
15871587

1588-
return (ffi.string(cname).decode('utf-8'), ffi.string(cemail).decode('utf-8'))
1588+
return (maybe_string(cname[0]), maybe_string(cemail[0]))
15891589

15901590
def set_ident(self, name: str, email: str) -> None:
15911591
"""Set the identity to be used for reference operations.

test/test_repository.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,19 @@ def test_default_signature(testrepo: Repository) -> None:
641641
assert 'rjh@example.com' == sig.email
642642

643643

644+
def test_ident_get_set(testrepo: Repository) -> None:
645+
# By default, reflog identity should be unset.
646+
assert testrepo.ident == (None, None)
647+
648+
cname = 'C O Mitter'
649+
cemail = 'committer@example.com'
650+
testrepo.set_ident(cname, cemail)
651+
assert testrepo.ident == (cname, cemail)
652+
653+
testrepo.set_ident(None, None)
654+
assert testrepo.ident == (None, None)
655+
656+
644657
def test_new_repo(tmp_path: Path) -> None:
645658
repo = init_repository(tmp_path, False)
646659

0 commit comments

Comments
 (0)