diff --git a/scmrepo/git/backend/dulwich/__init__.py b/scmrepo/git/backend/dulwich/__init__.py index 8dd8f355..761b5548 100644 --- a/scmrepo/git/backend/dulwich/__init__.py +++ b/scmrepo/git/backend/dulwich/__init__.py @@ -7,6 +7,7 @@ from io import BytesIO, StringIO from typing import ( TYPE_CHECKING, + Any, Callable, Dict, Iterable, @@ -344,8 +345,10 @@ def is_tracked(self, path: str) -> bool: return False def is_dirty(self, untracked_files: bool = False) -> bool: - staged, unstaged, untracked = self.status() - return bool(staged or unstaged or (untracked_files and untracked)) + kwargs: Dict[str, Any] = ( + {} if untracked_files else {"untracked_files": "no"} + ) + return any(self.status(**kwargs)) def active_branch(self) -> str: raise NotImplementedError diff --git a/tests/test_git.py b/tests/test_git.py index 3389ee9e..d40bbfb5 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -1041,3 +1041,70 @@ def test_status( assert staged["modify"] == ["foo"] assert unstaged == ["bar"] assert untracked == expected_untracked + + +@pytest.mark.skip_git_backend("pygit2") +def test_is_dirty_empty( + tmp_dir: TmpDir, + scm: Git, + git: Git, +): + assert not git.is_dirty() + + +@pytest.mark.skip_git_backend("pygit2") +def test_is_dirty_added( + tmp_dir: TmpDir, + scm: Git, + git: Git, +): + tmp_dir.gen("foo", "foo") + scm.add("foo") + + assert git.is_dirty() + scm.commit("commit") + assert not git.is_dirty() + + +@pytest.mark.skip_git_backend("pygit2") +def test_is_dirty_modified( + tmp_dir: TmpDir, + scm: Git, + git: Git, +): + tmp_dir.gen("foo", "foo") + scm.add_commit("foo", message="add foo") + + tmp_dir.gen("foo", "modified") + assert git.is_dirty() + scm.add_commit("foo", message="modified") + assert not git.is_dirty() + + +@pytest.mark.skip_git_backend("pygit2") +def test_is_dirty_deleted( + tmp_dir: TmpDir, + scm: Git, + git: Git, +): + tmp_dir.gen("foo", "foo") + scm.add_commit("foo", message="add foo") + + assert not git.is_dirty() + os.unlink(tmp_dir / "foo") + assert git.is_dirty() + scm.add("foo") + assert git.is_dirty() + scm.commit("deleted") + assert not git.is_dirty() + + +@pytest.mark.skip_git_backend("pygit2") +def test_is_dirty_untracked( + tmp_dir: TmpDir, + scm: Git, + git: Git, +): + tmp_dir.gen("untracked", "untracked") + assert git.is_dirty(untracked_files=True) + assert not git.is_dirty(untracked_files=False)