Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions pygit2/submodules.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from ._pygit2 import Oid
from .callbacks import RemoteCallbacks, git_fetch_options
from .enums import SubmoduleIgnore, SubmoduleStatus
from .errors import check_error
from .errors import AlreadyExistsError, check_error
from .ffi import C, ffi
from .utils import decode_fs_path, decode_string, encode_string

Expand Down Expand Up @@ -210,7 +210,11 @@ def get(self, name: str) -> Submodule | None:
"""
try:
return self[name]
except KeyError:
except (KeyError, AlreadyExistsError):
# libgit2 reports GIT_EEXISTS, which check_error turns into
# AlreadyExistsError, when a repository exists at the path but was
# never registered as a submodule. There is still no submodule by
# that name, so report it the same way as a missing one.
return None

def add(
Expand Down
19 changes: 19 additions & 0 deletions test/test_submodule.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,25 @@ def test_lookup_missing_submodule(repo: Repository) -> None:
assert repo.submodules.get('does-not-exist') is None


def test_lookup_nested_repo_that_is_not_a_submodule(tmp_path: Path) -> None:
"""A plain repository inside another is not a submodule.

libgit2 reports GIT_EEXISTS for this case rather than GIT_ENOTFOUND, which
reaches Python as AlreadyExistsError. get() and __contains__ must still
describe it as absent, per their documented contracts.
"""
outer = pygit2.init_repository(tmp_path / 'outer')
pygit2.init_repository(tmp_path / 'outer' / 'nested')

assert outer.submodules.get('nested') is None
assert 'nested' not in outer.submodules

# __getitem__ keeps reporting the distinction, so callers that care can
# still tell "there is a repository there" from "there is nothing there".
with pytest.raises(pygit2.AlreadyExistsError):
outer.submodules['nested']


def test_listall_submodules(repo: Repository) -> None:
submodules = repo.listall_submodules()
assert len(submodules) == 1
Expand Down
Loading