From 7caf28ca11af45435496c60eda2896ce30611c07 Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Wed, 6 Nov 2019 00:30:12 +0200 Subject: [PATCH] dvcignore: don't forget to use dvcignore when collecting dvcignores Fixes #2737 --- dvc/ignore.py | 15 ++++++++++++++- tests/func/test_ignore.py | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/dvc/ignore.py b/dvc/ignore.py index fe78b649f..3d111e868 100644 --- a/dvc/ignore.py +++ b/dvc/ignore.py @@ -6,6 +6,7 @@ import os from pathspec import PathSpec from pathspec.patterns import GitWildMatchPattern +from dvc.utils import dvc_walk from dvc.utils import relpath from dvc.utils.compat import open @@ -47,6 +48,9 @@ class DvcIgnorePatterns(DvcIgnore): return hash(self.ignore_file_path) def __eq__(self, other): + if not isinstance(other, DvcIgnorePatterns): + return NotImplemented + return self.ignore_file_path == other.ignore_file_path @@ -59,12 +63,21 @@ class DvcIgnoreDirs(DvcIgnore): return dirs, files + def __hash__(self): + return hash(tuple(self.basenames)) + + def __eq__(self, other): + if not isinstance(other, DvcIgnoreDirs): + return NotImplemented + + return self.basenames == other.basenames + class DvcIgnoreFilter(object): def __init__(self, root_dir): self.ignores = {DvcIgnoreDirs([".git", ".hg", ".dvc"])} self._update(root_dir) - for root, dirs, _ in os.walk(root_dir): + for root, dirs, _ in dvc_walk(root_dir, self): for d in dirs: self._update(os.path.join(root, d)) diff --git a/tests/func/test_ignore.py b/tests/func/test_ignore.py index 2b5fec7e9..6e38c2b02 100644 --- a/tests/func/test_ignore.py +++ b/tests/func/test_ignore.py @@ -5,6 +5,9 @@ import pytest from dvc.exceptions import DvcIgnoreInCollectedDirError from dvc.ignore import DvcIgnore +from dvc.ignore import DvcIgnoreDirs +from dvc.ignore import DvcIgnoreFilter +from dvc.ignore import DvcIgnorePatterns from dvc.utils.compat import cast_bytes from dvc.utils.fs import get_mtime_and_size from tests.basic_env import TestDvc @@ -131,3 +134,21 @@ def test_should_raise_on_dvcignore_in_out_dir(dvc_repo, repo_dir): with pytest.raises(DvcIgnoreInCollectedDirError): dvc_repo.add(repo_dir.DATA_DIR) + + +@pytest.mark.parametrize("dname", [TestDvc.DATA_DIR, TestDvc.DATA_SUB_DIR]) +def test_ignore_collecting_dvcignores(repo_dir, dname): + top_ignore_file = os.path.join( + repo_dir.root_dir, os.path.dirname(dname), DvcIgnore.DVCIGNORE_FILE + ) + repo_dir.create(top_ignore_file, os.path.basename(dname)) + + ignore_file = os.path.join( + repo_dir.root_dir, dname, DvcIgnore.DVCIGNORE_FILE + ) + repo_dir.create(ignore_file, repo_dir.FOO) + + assert DvcIgnoreFilter(repo_dir.root_dir).ignores == { + DvcIgnoreDirs([".git", ".hg", ".dvc"]), + DvcIgnorePatterns(top_ignore_file), + }