diff --git a/dvc/ignore.py b/dvc/ignore.py index 0e80a02103..f6d5afae15 100644 --- a/dvc/ignore.py +++ b/dvc/ignore.py @@ -64,7 +64,7 @@ def from_files(cls, ignore_file_path, tree): for line_no, line in enumerate( map(str.strip, fobj.readlines()) ) - if line + if line and not (line.strip().startswith("#")) ] return cls(path_spec_lines, dirname) @@ -314,3 +314,18 @@ def check_ignore(self, target): if matches: return CheckIgnoreResult(target, True, matches) return CheckIgnoreResult(target, False, ["::"]) + + +def init(path): + dvcignore = os.path.join(path, DvcIgnore.DVCIGNORE_FILE) + if os.path.exists(dvcignore): + return dvcignore + + with open(dvcignore, "w") as fobj: + fobj.write( + "# Add patterns of files dvc should ignore, which could improve\n" + "# the performance. Learn more at\n" + "# https://dvc.org/doc/user-guide/dvcignore\n" + ) + + return dvcignore diff --git a/dvc/repo/init.py b/dvc/repo/init.py index 695d83bcb3..67701c99d3 100644 --- a/dvc/repo/init.py +++ b/dvc/repo/init.py @@ -6,6 +6,7 @@ from dvc import analytics from dvc.config import Config from dvc.exceptions import InitError, InvalidArgumentError +from dvc.ignore import init as init_dvcignore from dvc.repo import Repo from dvc.scm import SCM from dvc.scm.base import SCMError @@ -99,9 +100,13 @@ def init(root_dir=os.curdir, no_scm=False, force=False, subdir=False): with config.edit() as conf: conf["core"]["no_scm"] = True + dvcignore = init_dvcignore(root_dir) + proj = Repo(root_dir) - scm.add([config.files["repo"], proj.plot_templates.templates_dir]) + scm.add( + [config.files["repo"], dvcignore, proj.plot_templates.templates_dir] + ) if scm.ignore_file: scm.add([os.path.join(dvc_dir, scm.ignore_file)]) diff --git a/tests/func/test_ignore.py b/tests/func/test_ignore.py index 67e8f71a5a..9543f4e4c5 100644 --- a/tests/func/test_ignore.py +++ b/tests/func/test_ignore.py @@ -132,6 +132,7 @@ def test_ignore_on_branch(tmp_dir, scm, dvc): assert set(dvc.tree.walk_files(path)) == { path / "foo", path / "bar", + path / ".dvcignore", } dvc.tree = scm.get_tree("branch", use_dvcignore=True) diff --git a/tests/func/test_init.py b/tests/func/test_init.py index 00fd8c90df..4ea9c9101e 100644 --- a/tests/func/test_init.py +++ b/tests/func/test_init.py @@ -101,3 +101,13 @@ def test_subdir_init_no_option(tmp_dir, scm, monkeypatch, caplog): "`--subdir` if initializing inside a subdirectory of a parent SCM " "repository.".format(os.fspath(tmp_dir / "subdir")) ) in caplog.text + + +def test_gen_dvcignore(tmp_dir): + DvcRepo.init(no_scm=True) + text = ( + "# Add patterns of files dvc should ignore, which could improve\n" + "# the performance. Learn more at\n" + "# https://dvc.org/doc/user-guide/dvcignore\n" + ) + assert text == (tmp_dir / ".dvcignore").read_text() diff --git a/tests/func/test_ls.py b/tests/func/test_ls.py index 85dd9eb1ba..4c2681d524 100644 --- a/tests/func/test_ls.py +++ b/tests/func/test_ls.py @@ -61,6 +61,7 @@ def test_ls_repo(tmp_dir, dvc, scm): match_files( files, ( + ((".dvcignore",), False), ((".gitignore",), False), (("README.md",), False), (("structure.xml.dvc",), False), @@ -89,6 +90,7 @@ def test_ls_repo_with_color(tmp_dir, dvc, scm, mocker, monkeypatch, caplog): assert caplog.records[-1].msg == "\n".join( [ + ".dvcignore", ".gitignore", "README.md", "\x1b[01;34mdata\x1b[0m", @@ -107,6 +109,7 @@ def test_ls_repo_recursive(tmp_dir, dvc, scm): match_files( files, ( + ((".dvcignore",), False), ((".gitignore",), False), (("README.md",), False), (("structure.xml.dvc",), False), @@ -258,6 +261,7 @@ def test_ls_repo_with_removed_dvc_dir(tmp_dir, dvc, scm): (("out.dvc",), False), (("dep",), True), (("out",), False), + ((".dvcignore",), False), ((".gitignore",), False), ), ) @@ -275,6 +279,7 @@ def test_ls_repo_with_removed_dvc_dir_recursive(tmp_dir, dvc, scm): (("out.dvc",), False), (("dep",), True), (("out", "file"), True), + ((".dvcignore",), False), ((".gitignore",), False), ), ) @@ -306,6 +311,7 @@ def test_ls_remote_repo(erepo_dir): match_files( files, ( + ((".dvcignore",), False), ((".gitignore",), False), (("README.md",), False), (("structure.xml.dvc",), False), @@ -326,6 +332,7 @@ def test_ls_remote_repo_recursive(erepo_dir): match_files( files, ( + ((".dvcignore",), False), ((".gitignore",), False), (("README.md",), False), (("structure.xml.dvc",), False), @@ -393,6 +400,7 @@ def test_ls_remote_repo_with_rev(erepo_dir): match_files( files, ( + ((".dvcignore",), False), ((".gitignore",), False), (("README.md",), False), (("model",), False), @@ -422,6 +430,7 @@ def test_ls_remote_repo_with_rev_recursive(erepo_dir): (("model", "people.csv"), True), (("model", ".gitignore"), False), (("structure.xml",), True), + ((".dvcignore",), False), ((".gitignore",), False), ), )