diff --git a/dvc/scm/git/__init__.py b/dvc/scm/git/__init__.py index d01e675d1..158a1545e 100644 --- a/dvc/scm/git/__init__.py +++ b/dvc/scm/git/__init__.py @@ -165,6 +165,10 @@ class Git(Base): filtered = list(filter(lambda x: x.strip() != entry.strip(), lines)) + if not filtered: + os.unlink(gitignore) + return + with open(gitignore, "w") as fobj: fobj.writelines(filtered) diff --git a/tests/func/test_remove.py b/tests/func/test_remove.py index 0faeb7dbe..f7f7536ba 100644 --- a/tests/func/test_remove.py +++ b/tests/func/test_remove.py @@ -29,7 +29,7 @@ def test_remove(tmp_dir, scm, dvc, run_copy, remove_outs): else: assert all(out_exists) - assert not any(out in get_gitignore_content() for out in stage.outs) + assert not (tmp_dir / ".gitignore").exists() def test_remove_non_existent_file(tmp_dir, dvc): @@ -69,3 +69,29 @@ def test_cmd_remove(tmp_dir, dvc): assert main(["remove", stage.addressing, "--outs"]) == 0 assert not (tmp_dir / stage.relpath).exists() assert not (tmp_dir / "foo").exists() + + +def test_cmd_remove_gitignore_single_stage(tmp_dir, scm, dvc, run_copy): + stage = dvc.run( + name="my", cmd='echo "hello" > out', deps=[], outs=["out"], + ) + + assert (tmp_dir / ".gitignore").exists() + + assert main(["remove", stage.addressing]) == 0 + assert not (tmp_dir / stage.relpath).exists() + assert not (stage.dvcfile._lockfile).exists() + assert not (tmp_dir / ".gitignore").exists() + + +def test_cmd_remove_gitignore_multistage(tmp_dir, scm, dvc, run_copy): + (stage,) = tmp_dir.dvc_gen("foo", "foo") + stage1 = run_copy("foo", "foo1", single_stage=True) + stage2 = run_copy("foo1", "foo2", name="copy-foo1-foo2") + + assert (tmp_dir / ".gitignore").exists() + + assert main(["remove", stage2.addressing]) == 0 + assert main(["remove", stage1.addressing]) == 0 + assert main(["remove", stage.addressing]) == 0 + assert not (tmp_dir / ".gitignore").exists() diff --git a/tests/func/test_scm.py b/tests/func/test_scm.py index f0ef1fb1c..ae5f9f700 100644 --- a/tests/func/test_scm.py +++ b/tests/func/test_scm.py @@ -85,7 +85,7 @@ def test_ignore(tmp_dir, scm): assert _count_gitignore_entries(target) == 1 scm.ignore_remove(foo) - assert _count_gitignore_entries(target) == 0 + assert not (tmp_dir / ".gitignore").exists() def test_ignored(tmp_dir, scm): diff --git a/tests/unit/scm/test_git.py b/tests/unit/scm/test_git.py index 12fe77519..edcbc4413 100644 --- a/tests/unit/scm/test_git.py +++ b/tests/unit/scm/test_git.py @@ -279,3 +279,25 @@ def test_list_all_commits(tmp_dir, scm): scm.set_ref("refs/foo/bar", rev_c) assert {rev_a, rev_b} == set(scm.list_all_commits()) + + +def test_ignore_remove_empty(tmp_dir, scm, git): + + test_entries = [ + {"entry": "/foo1", "path": f"{tmp_dir}/foo1"}, + {"entry": "/foo2", "path": f"{tmp_dir}/foo2"}, + ] + + path_to_gitignore = tmp_dir / ".gitignore" + + with open(path_to_gitignore, "a") as f: + for entry in test_entries: + f.write(entry["entry"] + "\n") + + assert path_to_gitignore.exists() + + git.ignore_remove(test_entries[0]["path"]) + assert path_to_gitignore.exists() + + git.ignore_remove(test_entries[1]["path"]) + assert not path_to_gitignore.exists()