commit - 699fde009ad0ee86b1ef7b1a619548f2006cc356
commit + 744fcc280f5a4e23f14598fb4630d1c76f33389b
blob - cb4bcad46b5bdbdaa150ea20aebef169cce2be60
blob + 1c1d8c4cb574c330838b5e118156315ec1e2ec44
--- dulwich/porcelain.py
+++ dulwich/porcelain.py
_import_remote_refs(r.refs, remote_name, fetch_result.refs)
-def status(repo=".", ignored=False, walk_untracked=True):
+def status(repo=".", ignored=False, untracked_files="all"):
"""Returns staged, unstaged, and untracked changes relative to the HEAD.
Args:
repo: Path to repository or repository object
ignored: Whether to include ignored files in untracked
- walk_untracked: Whether to walk untracked directories
- When True, behaves like `git status -uall`.
- When False, behaves like to `git status -unormal` (git default).
+ untracked_files: How to handle untracked files, defaults to "all":
+ "no": do not return untracked files
+ "all": include all files in untracked directories
+ Using `untracked_files="no"` can be faster than "all" when the worktreee
+ contains many untracked files/directories.
+
+ Note: `untracked_files="normal" (`git`'s default) is not implemented.
Returns: GitStatus tuple,
staged - dict with lists of staged paths (diff index/HEAD)
unstaged_changes = list(get_unstaged_changes(index, r.path, filter_callback))
untracked_paths = get_untracked_paths(
- r.path, r.path, index, exclude_ignored=not ignored, walk=walk_untracked
+ r.path,
+ r.path,
+ index,
+ exclude_ignored=not ignored,
+ untracked_files=untracked_files,
)
untracked_changes = list(untracked_paths)
def get_untracked_paths(
- frompath,
- basepath,
- index,
- exclude_ignored=False,
- walk=True,
+ frompath, basepath, index, exclude_ignored=False, untracked_files="all"
):
"""Get untracked paths.
basepath: Path to compare to
index: Index to check against
exclude_ignored: Whether to exclude ignored paths
- walk: Whether to walk untracked paths.
+ untracked_files: How to handle untracked files:
+ - "no": return an empty list
+ - "all": return all files in untracked directories
+ - "normal": Not implemented
Note: ignored directories will never be walked for performance reasons.
If exclude_ignored is False, only the path to an ignored directory will
be yielded, no files inside the directory will be returned
"""
+ if untracked_files == "normal":
+ raise NotImplementedError("normal is not yet supported")
+
+ if untracked_files not in ("no", "all"):
+ raise ValueError("untracked_files must be one of (no, all)")
+
+ if untracked_files == "no":
+ return
+
with open_repo_closing(basepath) as r:
ignore_manager = IgnoreFilterManager.from_repo(r)
ignored_dirs = []
- untracked_dirs = []
def prune_dirnames(dirpath, dirnames):
for i in range(len(dirnames) - 1, -1, -1):
os.path.join(os.path.relpath(path, frompath), "")
)
del dirnames[i]
- elif not walk:
- if not any(
- os.fsdecode(index_path).startswith(dirnames[i])
- for index_path, _, in index.items()
- ):
- untracked_dirs.append(
- os.path.join(os.path.relpath(path, frompath)) + os.sep
- )
- del dirnames[i]
return dirnames
for ap, is_dir in _walk_working_dir_paths(
yield os.path.relpath(ap, frompath)
yield from ignored_dirs
- yield from untracked_dirs
def get_tree_changes(repo):
blob - f70a6d678b3cc811898a69a67764ddb5039df79d
blob + 201669ebff9d296ddd2ea89404ca02dfa5debb6e
--- dulwich/tests/test_porcelain.py
+++ dulwich/tests/test_porcelain.py
mod_path = os.path.join(self.repo.path, "bar")
add_path = os.path.join(self.repo.path, "baz")
us_path = os.path.join(self.repo.path, "blye")
- ut_path = os.path.join(self.repo.path, "untracked_file")
- os.mkdir(os.path.join(self.repo.path, "untracked_dir"))
- ut_subfile_path = os.path.join(self.repo.path, "untracked_dir/file")
-
+ ut_path = os.path.join(self.repo.path, "blyat")
with open(del_path, "w") as f:
f.write("origstuff")
with open(mod_path, "w") as f:
f.write("origstuff")
with open(us_path, "w") as f:
f.write("origstuff")
- with open(ut_subfile_path, "w") as f:
- f.write("origstuff")
porcelain.add(repo=self.repo.path, paths=[del_path, mod_path, us_path])
porcelain.commit(
repo=self.repo.path,
results.staged,
)
self.assertListEqual(results.unstaged, [b"blye"])
- self.assertListEqual(
- results.untracked, [
- "untracked_file", os.path.join("untracked_dir", "file")]
- )
- results_no_walk = porcelain.status(self.repo.path, walk_untracked=False)
- self.assertListEqual(
- results_no_walk.untracked,
- ["untracked_file", "untracked_dir" + os.path.sep]
- )
+ results_no_untracked = porcelain.status(self.repo.path, untracked_files="no")
+ self.assertListEqual(results_no_untracked.untracked, [])
+ def test_status_wrong_untracked_files_value(self):
+ with self.assertRaises(ValueError):
+ porcelain.status(self.repo.path, untracked_files="antani")
+
def test_status_crlf_mismatch(self):
# First make a commit as if the file has been added on a Linux system
# or with core.autocrlf=True
self.repo.open_index(),
exclude_ignored=True,
)
- ),
+ )
)
- def test_get_untracked_paths_walk(self):
- os.mkdir(os.path.join(self.repo.path, "dir"))
- os.mkdir(os.path.join(self.repo.path, "dir/subdir"))
- with open(os.path.join(self.repo.path, "dir", "file"), "w") as f:
- f.write("foo")
- with open(os.path.join(self.repo.path, "dir/subdir/subfile"), "w") as f:
- f.write("foo")
-
- self.assertEqual(
- {"dir" + os.path.sep},
- set(
+ def test_get_untracked_paths_invalid_untracked_files(self):
+ with self.assertRaises(ValueError):
+ list(
porcelain.get_untracked_paths(
- self.repo.path, self.repo.path, self.repo.open_index(), walk=False
- )
- ),
- )
- self.assertEqual(
- set([os.path.join("dir", "file"),
- os.path.join("dir", "subdir", "subfile")]),
- set(
- porcelain.get_untracked_paths(
- self.repo.path, self.repo.path, self.repo.open_index(), walk=True
+ self.repo.path,
+ self.repo.path,
+ self.repo.open_index(),
+ untracked_files="invalid_value",
)
- ),
- )
+ )
+ def test_get_untracked_paths_normal(self):
+ with self.assertRaises(NotImplementedError):
+ _, _, _ = porcelain.status(
+ repo=self.repo.path, untracked_files="normal"
+ )
# TODO(jelmer): Add test for dulwich.porcelain.daemon