nebius/SWE-bench-extra huggingface dataset:
Repository: iterative/dvc

Issue:
metrics show all tags includes master branch
I was going through the `compare-experiments.md` and I faced the following expected output:

```bash
$ dvc metrics show -T

baseline-experiment:
    auc.metric: 0.588426
bigram-experiment:
    auc.metric: 0.602818
```

But mine was:

```bash
$ dvc metrics show -T
Working Tree:
	auc.metric: 0.620421
master:
	auc.metric: 0.588765
baseline-experiment:
	auc.metric: 0.588765
```

Although the output shows an understandable message, I assume there might be a previous step to create the `bigram-experiment` due to the presented context.

I see two solving options here:

- Adding the steps to create the `bigram-experiment` or
- Updating the expected output from `dvc metrics show -T`


Comments:
Looks like a minor bug in `dvc metrics show -T`. `master` should not be included. 

There is a step that creates `bigram-experiment`. @ricardoserradas, please check the `compare-experiments.md` once again:

```
git commit -a -m "evaluate bigram model"
git tag -a "bigram-experiment" -m "bigrams"
```

I would rename `Working Tree` to just `working tree` along the way. It's not a title or something.
Also need to adjust the docs.

Patch:
diff --git a/dvc/repo/brancher.py b/dvc/repo/brancher.py
--- a/dvc/repo/brancher.py
+++ b/dvc/repo/brancher.py
@@ -1,3 +1,6 @@
+from dvc.scm.tree import WorkingTree
+
+
 def brancher(  # noqa: E302
     self, branches=None, all_branches=False, tags=None, all_tags=False
 ):
@@ -24,11 +27,8 @@ def brancher(  # noqa: E302
 
     scm = self.scm
 
-    if self.scm.is_dirty():
-        from dvc.scm.tree import WorkingTree
-
-        self.tree = WorkingTree(self.root_dir)
-        yield "Working Tree"
+    self.tree = WorkingTree(self.root_dir)
+    yield "working tree"
 
     if all_branches:
         branches = scm.list_branches()
@@ -36,9 +36,7 @@ def brancher(  # noqa: E302
     if all_tags:
         tags = scm.list_tags()
 
-    if branches is None:
-        revs.extend([scm.active_branch()])
-    else:
+    if branches is not None:
         revs.extend(branches)
 
     if tags is not None:


Test patch:
diff --git a/tests/func/test_metrics.py b/tests/func/test_metrics.py
--- a/tests/func/test_metrics.py
+++ b/tests/func/test_metrics.py
@@ -706,6 +706,7 @@ def _test_metrics(self, func):
                 "master": {"metrics.json": ["master"]},
                 "one": {"metrics.json": ["one"]},
                 "two": {"metrics.json": ["two"]},
+                "working tree": {"metrics.json": ["two"]},
             },
         )
 
@@ -719,6 +720,7 @@ def _test_metrics(self, func):
                 "master": {"metrics.json": ["master"]},
                 "one": {"metrics.json": ["one"]},
                 "two": {"metrics.json": ["two"]},
+                "working tree": {"metrics.json": ["two"]},
             },
         )
Repository: iterative/dvc

Issue:
run: handle SIGINT gracefully
https://discordapp.com/channels/485586884165107732/485596304961962003/543461241289572352


Comments:

Patch:
diff --git a/dvc/stage.py b/dvc/stage.py
--- a/dvc/stage.py
+++ b/dvc/stage.py
@@ -7,6 +7,7 @@
 import os
 import subprocess
 import logging
+import signal
 
 from dvc.utils import relpath
 from dvc.utils.compat import pathlib
@@ -767,16 +768,22 @@ def _run(self):
         executable = os.getenv("SHELL") if os.name != "nt" else None
         self._warn_if_fish(executable)
 
-        p = subprocess.Popen(
-            self.cmd,
-            cwd=self.wdir,
-            shell=True,
-            env=fix_env(os.environ),
-            executable=executable,
-        )
-        p.communicate()
+        old_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
+        p = None
+
+        try:
+            p = subprocess.Popen(
+                self.cmd,
+                cwd=self.wdir,
+                shell=True,
+                env=fix_env(os.environ),
+                executable=executable,
+            )
+            p.communicate()
+        finally:
+            signal.signal(signal.SIGINT, old_handler)
 
-        if p.returncode != 0:
+        if (p is None) or (p.returncode != 0):
             raise StageCmdFailedError(self)
 
     def run(self, dry=False, resume=False, no_commit=False, force=False):


Test patch:
diff --git a/tests/func/test_run.py b/tests/func/test_run.py
--- a/tests/func/test_run.py
+++ b/tests/func/test_run.py
@@ -6,6 +6,7 @@
 import shutil
 import filecmp
 import subprocess
+import signal
 
 from dvc.main import main
 from dvc.output import OutputBase
@@ -323,9 +324,46 @@ def test_run_args_with_spaces(self):
         self.assertEqual(ret, 0)
         self.assertEqual(stage.cmd, 'echo "foo bar"')
 
-    @mock.patch.object(subprocess, "Popen", side_effect=KeyboardInterrupt)
-    def test_keyboard_interrupt(self, _):
-        ret = main(["run", "mycmd"])
+    @mock.patch.object(subprocess.Popen, "wait", new=KeyboardInterrupt)
+    def test_keyboard_interrupt(self):
+        ret = main(
+            [
+                "run",
+                "-d",
+                self.FOO,
+                "-d",
+                self.CODE,
+                "-o",
+                "out",
+                "-f",
+                "out.dvc",
+                "python",
+                self.CODE,
+                self.FOO,
+                "out",
+            ]
+        )
+        self.assertEqual(ret, 1)
+
+    @mock.patch.object(signal, "signal", side_effect=[None, KeyboardInterrupt])
+    def test_keyboard_interrupt_after_second_signal_call(self, _):
+        ret = main(
+            [
+                "run",
+                "-d",
+                self.FOO,
+                "-d",
+                self.CODE,
+                "-o",
+                "out",
+                "-f",
+                "out.dvc",
+                "python",
+                self.CODE,
+                self.FOO,
+                "out",
+            ]
+        )
         self.assertEqual(ret, 252)
Repository: iterative/dvc

Issue:
destroy: don't remove data files by default in the workspace
Will have to add some option to destroy data files as well.


Comments:
@efiop , `destroy` should work as `rm -rf .dvc`?

I was thinking about adding the `--all` option that will work as `rm -rf .dvc *.dvc Dvcfile`.

Is that the expected behavior?
Currently `destroy` removes both .dvc/ directory and *.dvc files with their outputs. Starting from 1.0, it should leave outputs intact(in symlink case, it should remove symlinks and replace them by copies), so that user at least has his data back.
We should use `unprotect` as described in https://github.com/iterative/dvc/issues/1802

Patch:
diff --git a/dvc/repo/destroy.py b/dvc/repo/destroy.py
--- a/dvc/repo/destroy.py
+++ b/dvc/repo/destroy.py
@@ -3,6 +3,6 @@
 
 def destroy(self):
     for stage in self.stages():
-        stage.remove()
+        stage.remove(remove_outs=False)
 
     shutil.rmtree(self.dvc_dir)
diff --git a/dvc/stage.py b/dvc/stage.py
--- a/dvc/stage.py
+++ b/dvc/stage.py
@@ -296,8 +296,11 @@ def unprotect_outs(self):
         for out in self.outs:
             out.unprotect()
 
-    def remove(self, force=False):
-        self.remove_outs(ignore_remove=True, force=force)
+    def remove(self, force=False, remove_outs=True):
+        if remove_outs:
+            self.remove_outs(ignore_remove=True, force=force)
+        else:
+            self.unprotect_outs()
         os.unlink(self.path)
 
     def reproduce(


Test patch:
diff --git a/tests/func/test_destroy.py b/tests/func/test_destroy.py
--- a/tests/func/test_destroy.py
+++ b/tests/func/test_destroy.py
@@ -1,21 +1,28 @@
 import os
 
-from dvc.main import main
+from dvc.system import System
 
-from tests.func.test_repro import TestRepro
 
+def test_destroy(repo_dir, dvc_repo):
+    # NOTE: using symlink to ensure that data was unprotected after `destroy`
+    dvc_repo.config.set("cache", "type", "symlink")
 
-class TestDestroyNoConfirmation(TestRepro):
-    def test(self):
-        ret = main(["destroy"])
-        self.assertNotEqual(ret, 0)
+    foo_stage, = dvc_repo.add(repo_dir.FOO)
+    data_dir_stage, = dvc_repo.add(repo_dir.DATA_DIR)
 
+    dvc_repo.destroy()
 
-class TestDestroyForce(TestRepro):
-    def test(self):
-        ret = main(["destroy", "-f"])
-        self.assertEqual(ret, 0)
+    assert not os.path.exists(dvc_repo.dvc_dir)
+    assert not os.path.exists(foo_stage.path)
+    assert not os.path.exists(data_dir_stage.path)
 
-        self.assertFalse(os.path.exists(self.dvc.dvc_dir))
-        self.assertFalse(os.path.exists(self.file1_stage))
-        self.assertFalse(os.path.exists(self.file1))
+    assert os.path.isfile(repo_dir.FOO)
+    assert os.path.isdir(repo_dir.DATA_DIR)
+    assert os.path.isfile(repo_dir.DATA)
+    assert os.path.isdir(repo_dir.DATA_SUB_DIR)
+    assert os.path.isfile(repo_dir.DATA_SUB)
+
+    assert not System.is_symlink(repo_dir.FOO)
+    assert not System.is_symlink(repo_dir.DATA_DIR)
+    assert not System.is_symlink(repo_dir.DATA)
+    assert not System.is_symlink(repo_dir.DATA_SUB)
Repository: iterative/dvc

Issue:
Metrics show xpath does not override dvcfile xpath

I do have a Dvcfile with metrics, and for some period of time (a few commits) I defined a specific xpath in that file; Now, when I run a different xpath on `dvc metrics show`, the old xpath (and hense, different metric) shows up for the commits where dvcfile specified it:

```
>>> dvc metric show -x pe20

working tree:
        data/rentals/nyc/metrics.json: [88.15]
bin_bedroom:
        data/rentals/nyc/metrics.json: [88.25]
first-iteration:
        data/rentals/nyc/metrics.json: [88.13]
nhds:
        data/rentals/nyc/metrics.json: [7.45]
roosevelt:
        data/rentals/nyc/metrics.json: [7.11]
``` 

obviosly pe20 was > 88 for all the commits, it's just showing median error for the `nhds` and `roosevelt`



Comments:
Thanks for reporting @Casyfill ! Indeed, we need to override it. We'll take a look.
You probably can instead just check for the xpath in the current Dvcfile, and override it with the explicit path, if needed? 
@Casyfill Yes, the explicitly specified xpath should override the one specified in a dvc file.

Patch:
diff --git a/dvc/repo/metrics/show.py b/dvc/repo/metrics/show.py
--- a/dvc/repo/metrics/show.py
+++ b/dvc/repo/metrics/show.py
@@ -188,10 +188,16 @@ def _collect_metrics(repo, path, recursive, typ, xpath, branch):
         if not o.metric:
             continue
 
+        # NOTE this case assumes that metric has been modified with
+        # `dvc metric modify -t {} -x {}`, so stage file should contain
+        # info what type metric is and what is its xpath
         if not typ and isinstance(o.metric, dict):
             t = o.metric.get(o.PARAM_METRIC_TYPE, typ)
-            x = o.metric.get(o.PARAM_METRIC_XPATH, xpath)
+            # NOTE user might want to check different xpath, hence xpath first
+            x = xpath or o.metric.get(o.PARAM_METRIC_XPATH)
         else:
+            # NOTE if metric has not been modified, user needs to provide
+            # both metric type and xpath
             t = typ
             x = xpath
 


Test patch:
diff --git a/tests/func/test_metrics.py b/tests/func/test_metrics.py
--- a/tests/func/test_metrics.py
+++ b/tests/func/test_metrics.py
@@ -831,3 +831,16 @@ def test(self, git, dvc_repo, caplog):
             in caplog.text
         )
         assert 0 == ret
+
+
+def test_show_xpath_should_override_stage_xpath(dvc_repo):
+    metric_file = "metric"
+    metric = {"m1": 0.1, "m2": 0.2}
+    with open(metric_file, "w") as fobj:
+        json.dump(metric, fobj)
+
+    dvc_repo.run(cmd="", overwrite=True, metrics=[metric_file])
+    dvc_repo.metrics.modify(metric_file, typ="json", xpath="m2")
+
+    result = dvc_repo.metrics.show(xpath="m1")
+    assert result == {"": {metric_file: [0.1]}}
Repository: iterative/dvc

Issue:
git checkout some-file causes dvc to try to remove a dvc-managed file
When I `git checkout some-file` to clean away my local changes to that file, the dvc hook butts in and says:

> ERROR: unexpected error - unable to remove 'data/qix/1a285cea-7b71-4492-9b4d-87092bfb9869.json.gz' without a confirmation from the user. Use '-f' to force.

But I did not request removal of that file, and I don't understand why DVC is trying to do that.

Note that I'm _not_ switching to a different branch/tag/commit, because I specified a path to `git checkout`. So I'm only modifying files in my working tree. I don't think that should trigger DVC to [try to] remove files.

Platform: macOS, Python 3.7.4 virtualenv installed using `pyenv`, and:
```bash
$ dvc --version
0.54.1+5e4d26
```


Comments:
@gthb Thanks for reporting this! Looks like we are not using post-checkout parameters that are being passed to us by git and are indicating if we are checking out a specific file or a branch/tag/etc. https://git-scm.com/docs/githooks#_post_checkout We need to adjust our hook accordingly.
@gthb Looks like the third parameter is just what we need. You could try modifying your git hook by hand to see if that will do the job for you. If it does, please let us know, and maybe consider submitting a PR, we really appreciate your contributions :slightly_smiling_face: If it doesn't work, please ping us as well.

Patch:
diff --git a/dvc/scm/git/__init__.py b/dvc/scm/git/__init__.py
--- a/dvc/scm/git/__init__.py
+++ b/dvc/scm/git/__init__.py
@@ -216,7 +216,11 @@ def list_tags(self):
         return [t.name for t in self.repo.tags]
 
     def _install_hook(self, name, cmd):
-        command = '[ -z "$(git ls-files .dvc)" ] || exec dvc {}'.format(cmd)
+        command = (
+            '[ "$3" == "0" ]'
+            ' || [ -z "$(git ls-files .dvc)" ]'
+            " || exec dvc {}".format(cmd)
+        )
 
         hook = os.path.join(self.root_dir, self.GIT_DIR, "hooks", name)
 


Test patch:
diff --git a/tests/func/test_install.py b/tests/func/test_install.py
--- a/tests/func/test_install.py
+++ b/tests/func/test_install.py
@@ -39,7 +39,9 @@ def test_should_append_hooks_if_file_already_exists(self, git, dvc_repo):
         expected_script = (
             "#!/bin/sh\n"
             "echo hello\n"
-            '[ -z "$(git ls-files .dvc)" ] || exec dvc checkout\n'
+            '[ "$3" == "0" ]'
+            ' || [ -z "$(git ls-files .dvc)" ]'
+            " || exec dvc checkout\n"
         )
 
         with open(self._hook("post-checkout"), "r") as fobj:
@@ -51,7 +53,9 @@ def test_should_be_idempotent(self, git, dvc_repo):
 
         expected_script = (
             "#!/bin/sh\n"
-            '[ -z "$(git ls-files .dvc)" ] || exec dvc checkout\n'
+            '[ "$3" == "0" ]'
+            ' || [ -z "$(git ls-files .dvc)" ]'
+            " || exec dvc checkout\n"
         )
 
         with open(self._hook("post-checkout"), "r") as fobj:
Repository: iterative/dvc

Issue:
Dvc add data unprotect files for each use
My DVC version 
![image](https://user-images.githubusercontent.com/20395242/59399222-dac61880-8dc5-11e9-88db-c5fc4e232d56.png)

This issue comes from **Share NAS data in serve**r in the [discuss post 11#](https://discuss.dvc.org/t/share-nas-data-in-server/180/11?u=jimmy15923)

When adding new data, dvc will unprotect all data which cost lots of time (about 20 mins) which seems inevitable.

![image](https://user-images.githubusercontent.com/20395242/59399331-2aa4df80-8dc6-11e9-9aa2-f0c2ef9d4b01.png)

Dvc add data unprotect files for each use
My DVC version 
![image](https://user-images.githubusercontent.com/20395242/59399222-dac61880-8dc5-11e9-88db-c5fc4e232d56.png)

This issue comes from **Share NAS data in serve**r in the [discuss post 11#](https://discuss.dvc.org/t/share-nas-data-in-server/180/11?u=jimmy15923)

When adding new data, dvc will unprotect all data which cost lots of time (about 20 mins) which seems inevitable.

![image](https://user-images.githubusercontent.com/20395242/59399331-2aa4df80-8dc6-11e9-9aa2-f0c2ef9d4b01.png)



Comments:
+1

I unprotected and changed a single file in a directory. dvc add for this directory makes unnecessary unprotection and copy of other files.
+1

I unprotected and changed a single file in a directory. dvc add for this directory makes unnecessary unprotection and copy of other files.

Patch:
diff --git a/dvc/stage.py b/dvc/stage.py
--- a/dvc/stage.py
+++ b/dvc/stage.py
@@ -505,8 +505,6 @@ def create(repo, **kwargs):
             stage.remove_outs(ignore_remove=False)
             logger.warning("Build cache is ignored when using --remove-outs.")
             ignore_build_cache = True
-        else:
-            stage.unprotect_outs()
 
         if os.path.exists(path) and any(out.persist for out in stage.outs):
             logger.warning("Build cache is ignored when persisting outputs.")


Test patch:
diff --git a/tests/func/test_add.py b/tests/func/test_add.py
--- a/tests/func/test_add.py
+++ b/tests/func/test_add.py
@@ -12,6 +12,7 @@
 import logging
 import colorama
 
+from dvc.remote import RemoteLOCAL
 from dvc.system import System
 from mock import patch
 
@@ -535,3 +536,20 @@ def test_windows_should_add_when_cache_on_different_drive(
 
     ret = main(["add", repo_dir.DATA])
     assert ret == 0
+
+
+def test_readding_dir_should_not_unprotect_all(dvc_repo, repo_dir):
+    dvc_repo.cache.local.cache_types = ["symlink"]
+    dvc_repo.cache.local.protected = True
+
+    dvc_repo.add(repo_dir.DATA_DIR)
+    new_file = os.path.join(repo_dir.DATA_DIR, "new_file")
+
+    repo_dir.create(new_file, "new_content")
+
+    unprotect_spy = spy(RemoteLOCAL.unprotect)
+    with patch.object(RemoteLOCAL, "unprotect", unprotect_spy):
+        dvc_repo.add(repo_dir.DATA_DIR)
+
+    assert not unprotect_spy.mock.called
+    assert System.is_symlink(new_file)
Repository: iterative/dvc

Issue:
get: error while fetching DVC-file
`dvc get` is to download data artifacts, but if the user hasn't this clear, they might try to `get` a DVC-file and the error is not that clear.

```
❯ dvc get https://github.com/iterative/dvc scripts/innosetup/dvc.ico.dvc
ERROR: failed to get 'scripts/innosetup/dvc.ico.dvc' from 'https://github.com/iterative/dvc' - unable to find DVC-file with output '../../../tmp/tmpbzwhrmqcdvc-repo/scripts/innosetup/dvc.ico.dvc'
```

I suggest showing a message to guard from this behavior:
```
ERROR: failed to get 'scripts/innosetup/dvc.ico.dvc' from 'https://github.com/iterative/dvc' - this is a DVC-file, you must specify the path of an output
```


Comments:

Patch:
diff --git a/dvc/exceptions.py b/dvc/exceptions.py
--- a/dvc/exceptions.py
+++ b/dvc/exceptions.py
@@ -286,3 +286,11 @@ def __init__(self, url):
         super(UrlNotDvcRepoError, self).__init__(
             "URL '{}' is not a dvc repository.".format(url)
         )
+
+
+class GetDVCFileError(DvcException):
+    def __init__(self):
+        super(GetDVCFileError, self).__init__(
+            "the given path is a DVC-file, you must specify a data file "
+            "or a directory"
+        )
diff --git a/dvc/repo/get.py b/dvc/repo/get.py
--- a/dvc/repo/get.py
+++ b/dvc/repo/get.py
@@ -2,8 +2,9 @@
 import os
 import shortuuid
 
+from dvc.stage import Stage
 from dvc.config import Config
-from dvc.exceptions import NotDvcRepoError, UrlNotDvcRepoError
+from dvc.exceptions import NotDvcRepoError, UrlNotDvcRepoError, GetDVCFileError
 from dvc.path_info import PathInfo
 from dvc.external_repo import external_repo
 from dvc.state import StateNoop
@@ -17,6 +18,9 @@
 def get(url, path, out=None, rev=None):
     out = out or os.path.basename(urlparse(path).path)
 
+    if Stage.is_valid_filename(out):
+        raise GetDVCFileError()
+
     # Creating a directory right beside the output to make sure that they
     # are on the same filesystem, so we could take the advantage of
     # reflink and/or hardlink. Not using tempfile.TemporaryDirectory


Test patch:
diff --git a/tests/func/test_get.py b/tests/func/test_get.py
--- a/tests/func/test_get.py
+++ b/tests/func/test_get.py
@@ -3,7 +3,7 @@
 
 import pytest
 
-from dvc.exceptions import UrlNotDvcRepoError
+from dvc.exceptions import UrlNotDvcRepoError, GetDVCFileError
 from dvc.repo import Repo
 
 from tests.utils import trees_equal
@@ -46,3 +46,8 @@ def test_get_repo_rev(repo_dir, erepo):
 def test_get_from_non_dvc_repo(git_erepo):
     with pytest.raises(UrlNotDvcRepoError):
         Repo.get(git_erepo.root_dir, "some_file.zip")
+
+
+def test_get_a_dvc_file(repo_dir, erepo):
+    with pytest.raises(GetDVCFileError):
+        Repo.get(erepo.root_dir, "some_file.dvc")
Repository: iterative/dvc

Issue:
stage: don't write default wdir
https://github.com/iterative/dvc/blob/0.57.0/dvc/stage.py#L632

`.` doesn't evaluate to False and so not skipped.


Comments:
@efiop , related? https://github.com/iterative/dvc/issues/2210
What is the reasoning for not writing `wdir`? We actually have [test](https://github.com/iterative/dvc/blob/41351a2df2f36ed04846d5e3d976d6d99b71a151/tests/func/test_run.py#L563) checking that wdir `.` is written.

Patch:
diff --git a/dvc/stage.py b/dvc/stage.py
--- a/dvc/stage.py
+++ b/dvc/stage.py
@@ -629,12 +629,16 @@ def load(repo, fname):
 
     def dumpd(self):
         rel_wdir = relpath(self.wdir, os.path.dirname(self.path))
+
+        wdir = pathlib.PurePath(rel_wdir).as_posix()
+        wdir = wdir if wdir != "." else None
+
         return {
             key: value
             for key, value in {
                 Stage.PARAM_MD5: self.md5,
                 Stage.PARAM_CMD: self.cmd,
-                Stage.PARAM_WDIR: pathlib.PurePath(rel_wdir).as_posix(),
+                Stage.PARAM_WDIR: wdir,
                 Stage.PARAM_LOCKED: self.locked,
                 Stage.PARAM_DEPS: [d.dumpd() for d in self.deps],
                 Stage.PARAM_OUTS: [o.dumpd() for o in self.outs],


Test patch:
diff --git a/tests/func/test_run.py b/tests/func/test_run.py
--- a/tests/func/test_run.py
+++ b/tests/func/test_run.py
@@ -560,18 +560,18 @@ def test_not_cached(self):
 
 
 class TestCmdRunWorkingDirectory(TestDvc):
-    def test_default_wdir_is_written(self):
+    def test_default_wdir_is_not_written(self):
         stage = self.dvc.run(
             cmd="echo test > {}".format(self.FOO), outs=[self.FOO], wdir="."
         )
         d = load_stage_file(stage.relpath)
-        self.assertEqual(d[Stage.PARAM_WDIR], ".")
+        self.assertNotIn(Stage.PARAM_WDIR, d.keys())
 
         stage = self.dvc.run(
             cmd="echo test > {}".format(self.BAR), outs=[self.BAR]
         )
         d = load_stage_file(stage.relpath)
-        self.assertEqual(d[Stage.PARAM_WDIR], ".")
+        self.assertNotIn(Stage.PARAM_WDIR, d.keys())
 
     def test_fname_changes_path_and_wdir(self):
         dname = "dir"
diff --git a/tests/func/test_stage.py b/tests/func/test_stage.py
--- a/tests/func/test_stage.py
+++ b/tests/func/test_stage.py
@@ -102,16 +102,10 @@ def test_ignored_in_checksum(self):
         )
 
         d = stage.dumpd()
-        self.assertEqual(d[stage.PARAM_WDIR], ".")
+        self.assertNotIn(Stage.PARAM_WDIR, d.keys())
 
         d = load_stage_file(stage.relpath)
-        self.assertEqual(d[stage.PARAM_WDIR], ".")
-
-        del d[stage.PARAM_WDIR]
-        dump_stage_file(stage.relpath, d)
-
-        d = load_stage_file(stage.relpath)
-        self.assertIsNone(d.get(stage.PARAM_WDIR))
+        self.assertNotIn(Stage.PARAM_WDIR, d.keys())
 
         with self.dvc.state:
             stage = Stage.load(self.dvc, stage.relpath)