diff --git a/src/scmrepo/git/backend/dulwich/__init__.py b/src/scmrepo/git/backend/dulwich/__init__.py index d36bda2a..ad6821c8 100644 --- a/src/scmrepo/git/backend/dulwich/__init__.py +++ b/src/scmrepo/git/backend/dulwich/__init__.py @@ -646,15 +646,16 @@ def determine_wants( if remote_refs[lh] not in self.repo.object_store ] - try: + with reraise( + Exception, SCMError(f"'{url}' is not a valid Git remote or URL") + ): _remote, location = get_remote_repo(self.repo, url) client, path = get_transport_and_path(location, **kwargs) - except Exception as exc: - raise SCMError( - f"'{url}' is not a valid Git remote or URL" - ) from exc - try: + with reraise( + (NotGitRepository, KeyError), + SCMError(f"Git failed to fetch ref from '{url}'"), + ): fetch_result = client.fetch( path, self.repo, @@ -663,37 +664,37 @@ def determine_wants( else None, determine_wants=determine_wants, ) - except NotGitRepository as exc: - raise SCMError(f"Git failed to fetch ref from '{url}'") from exc - - result = {} - - for (lh, rh, _) in fetch_refs: - refname = os.fsdecode(rh) - if rh in self.repo.refs: - if self.repo.refs[rh] == fetch_result.refs[lh]: - result[refname] = SyncStatus.UP_TO_DATE - continue - try: - check_diverged( - self.repo, self.repo.refs[rh], fetch_result.refs[lh] - ) - except DivergedBranches: - if not force: - overwrite = ( - on_diverged( - os.fsdecode(rh), - os.fsdecode(fetch_result.refs[lh]), - ) - if on_diverged - else False + + result = {} + + for (lh, rh, _) in fetch_refs: + refname = os.fsdecode(rh) + if rh in self.repo.refs: + if self.repo.refs[rh] == fetch_result.refs[lh]: + result[refname] = SyncStatus.UP_TO_DATE + continue + try: + check_diverged( + self.repo, + self.repo.refs[rh], + fetch_result.refs[lh], ) - if not overwrite: - result[refname] = SyncStatus.DIVERGED - continue + except DivergedBranches: + if not force: + overwrite = ( + on_diverged( + os.fsdecode(rh), + os.fsdecode(fetch_result.refs[lh]), + ) + if on_diverged + else False + ) + if not overwrite: + result[refname] = SyncStatus.DIVERGED + continue - self.repo.refs[rh] = fetch_result.refs[lh] - result[refname] = SyncStatus.SUCCESS + self.repo.refs[rh] = fetch_result.refs[lh] + result[refname] = SyncStatus.SUCCESS return result def _stash_iter(self, ref: str): diff --git a/tests/test_git.py b/tests/test_git.py index 070e52f9..08c98f7c 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -5,7 +5,9 @@ import pytest from asyncssh import SFTPClient from asyncssh.connection import SSHClientConnection +from dulwich.client import LocalGitClient from git import Repo as GitPythonRepo +from pytest_mock import MockerFixture from pytest_test_utils import TempDirFactory, TmpDir from pytest_test_utils.matchers import Matcher @@ -325,6 +327,7 @@ def test_fetch_refspecs( git: Git, remote_git_dir: TmpDir, use_url: bool, + mocker: MockerFixture, ): from scmrepo.git.backend.dulwich import SyncStatus @@ -370,6 +373,10 @@ def test_fetch_refspecs( } assert baz_rev == scm.get_ref("refs/foo/baz") + with pytest.raises(SCMError): + mocker.patch.object(LocalGitClient, "fetch", side_effect=KeyError) + git.fetch_refspecs(remote, "refs/foo/bar:refs/foo/bar") + @pytest.mark.skip_git_backend("pygit2", "gitpython") @pytest.mark.parametrize("use_url", [True, False])