Skip to content

Commit c6398b9

Browse files
committed
git: add untracked_files kwarg to status()
note that this currently is only available in dulwich>=0.20.38
1 parent f0ef4e5 commit c6398b9

File tree

5 files changed

+67
-5
lines changed

5 files changed

+67
-5
lines changed

scmrepo/git/backend/base.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ def checkout_index(
330330

331331
@abstractmethod
332332
def status(
333-
self, ignored: bool = False
333+
self, ignored: bool = False, untracked_files: str = "all"
334334
) -> Tuple[Mapping[str, Iterable[str]], Iterable[str], Iterable[str]]:
335335
"""Return tuple of (staged_files, unstaged_files, untracked_files).
336336
@@ -339,6 +339,15 @@ def status(
339339
340340
If ignored is True, gitignored files will be included in
341341
untracked_paths.
342+
343+
untracked_files can be one of the following:
344+
- "no" return no untracked files
345+
- "normal" (git cli default) return untracked files and directories
346+
- "all" (default) return all untracked files in untracked directories
347+
348+
Using "no" or "normal" will be faster than "all" when large untracked
349+
directories are present in the workspace, as collecting all untracked
350+
files can take some time.
342351
"""
343352

344353
def _reset(self) -> None:

scmrepo/git/backend/dulwich/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -750,12 +750,12 @@ def checkout_index(
750750
raise NotImplementedError
751751

752752
def status(
753-
self, ignored: bool = False
753+
self, ignored: bool = False, untracked_files: str = "all"
754754
) -> Tuple[Mapping[str, Iterable[str]], Iterable[str], Iterable[str]]:
755755
from dulwich.porcelain import status as git_status
756756

757757
staged, unstaged, untracked = git_status(
758-
self.root_dir, ignored=ignored
758+
self.root_dir, ignored=ignored, untracked_files=untracked_files
759759
)
760760
return (
761761
{

scmrepo/git/backend/gitpython.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ def checkout_index(
615615
self.repo.index.checkout(paths=paths_list, force=force)
616616

617617
def status(
618-
self, ignored: bool = False
618+
self, ignored: bool = False, untracked_files: str = "all"
619619
) -> Tuple[Mapping[str, Iterable[str]], Iterable[str], Iterable[str]]:
620620
raise NotImplementedError
621621

scmrepo/git/backend/pygit2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ def iter_remote_refs(self, url: str, base: Optional[str] = None, **kwargs):
594594
raise NotImplementedError
595595

596596
def status(
597-
self, ignored: bool = False
597+
self, ignored: bool = False, untracked_files: str = "all"
598598
) -> Tuple[Mapping[str, Iterable[str]], Iterable[str], Iterable[str]]:
599599
raise NotImplementedError
600600

tests/test_git.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,3 +988,56 @@ def test_fetch(
988988

989989
target.fetch()
990990
assert target.get_ref("refs/remotes/origin/master") == rev
991+
992+
993+
@pytest.mark.skip_git_backend("pygit2", "gitpython")
994+
@pytest.mark.parametrize("untracked_files", ["all", "no"])
995+
@pytest.mark.parametrize("ignored", [False, True])
996+
def test_status(
997+
tmp_dir: TmpDir,
998+
scm: Git,
999+
git: Git,
1000+
tmp_dir_factory: TempDirFactory,
1001+
untracked_files: str,
1002+
ignored: bool,
1003+
):
1004+
tmp_dir.gen(
1005+
{
1006+
"foo": "foo",
1007+
"bar": "bar",
1008+
".gitignore": "ignored",
1009+
"ignored": "ignored",
1010+
}
1011+
)
1012+
scm.add_commit(["foo", "bar", ".gitignore"], message="init")
1013+
1014+
staged, unstaged, untracked = git.status(ignored, untracked_files)
1015+
1016+
assert not staged
1017+
assert not unstaged
1018+
if ignored and untracked_files != "no":
1019+
assert untracked == ["ignored"]
1020+
else:
1021+
assert not untracked
1022+
1023+
with (tmp_dir / "foo").open("a") as fh:
1024+
fh.write("modified")
1025+
1026+
with (tmp_dir / "bar").open("a") as fh:
1027+
fh.write("modified")
1028+
1029+
tmp_dir.gen({"untracked_dir": {"subfolder": {"subfile": "subfile"}}})
1030+
expected_untracked = []
1031+
if ignored and untracked_files != "no":
1032+
expected_untracked.append("ignored")
1033+
if untracked_files != "no":
1034+
expected_untracked.append(
1035+
os.path.join("untracked_dir", "subfolder", "subfile")
1036+
)
1037+
1038+
git.add("foo")
1039+
staged, unstaged, untracked = git.status(ignored, untracked_files)
1040+
1041+
assert staged["modify"] == ["foo"]
1042+
assert unstaged == ["bar"]
1043+
assert untracked == expected_untracked

0 commit comments

Comments
 (0)