anon-iclr-submission/benchname-bug-localization huggingface dataset:
Repository: iterative/dvc
Issue: permissions are not set right for directories DVC creates

* Potentially affects shared cache group logic which can be a security issue?
* Affects all local commands that create directories which is also a security issue.

**For example: **

`dvc get https://github.com/iterative/dataset-registry get-started/data.xml -o data/data.xml`

creates an intermediate directory `data` with `0o777` permissions on Mac in `~` and `/tmp`:

```
drwxrwxrwx  3 ivan  wheel    96B Nov 13 12:47 data
```

It might be related to this [note](https://docs.python.org/3/library/os.html#os.makedirs): 

> Changed in version 3.7: The mode argument no longer affects the file permission bits of newly-created intermediate-level directories.

It also can be reproduced on Linux. More context here - https://discordapp.com/channels/485586884165107732/565699007037571084/644272213331279872


Changed files:
tests/func/test_utils.py, dvc/utils/compat.py, dvc/utils/__init__.py

diff --git a/dvc/utils/__init__.py b/dvc/utils/__init__.py
index 864c9e5f5..a7e9ab5f4 100644
--- a/dvc/utils/__init__.py
+++ b/dvc/utils/__init__.py
@@ -152,9 +152,12 @@ def makedirs(path, exist_ok=False, mode=None):
         _makedirs(path, exist_ok=exist_ok)
         return
 
-    umask = os.umask(0)
+    # utilize umask to set proper permissions since Python 3.7 the `mode`
+    # `makedirs` argument no longer affects the file permission bits of
+    # newly-created intermediate-level directories.
+    umask = os.umask(0o777 - mode)
     try:
-        _makedirs(path, exist_ok=exist_ok, mode=mode)
+        _makedirs(path, exist_ok=exist_ok)
     finally:
         os.umask(umask)
 
diff --git a/dvc/utils/compat.py b/dvc/utils/compat.py
index 7d66dd090..4863e4a56 100644
--- a/dvc/utils/compat.py
+++ b/dvc/utils/compat.py
@@ -85,8 +85,6 @@ def _makedirs(name, mode=0o777, exist_ok=False):
             if e.errno != errno.EEXIST:
                 raise
         cdir = os.curdir
-        if isinstance(tail, bytes):
-            cdir = bytes(os.curdir, "ASCII")
         if tail == cdir:
             return
     try:
diff --git a/tests/func/test_utils.py b/tests/func/test_utils.py
index 73f489e25..594fdc332 100644
--- a/tests/func/test_utils.py
+++ b/tests/func/test_utils.py
@@ -1,6 +1,10 @@
+# encoding: utf-8
 import filecmp
 import os
 import shutil
+import stat
+
+import pytest
 
 from dvc import utils
 from tests.basic_env import TestDvc
@@ -69,3 +73,18 @@ class TestUtils(TestDvc):
         )
 
         assert expected == utils.boxify("message")
+
+
+@pytest.mark.skipif(os.name == "nt", reason="Not supported for Windows.")
+def test_makedirs_permissions(tmpdir):
+    dir_mode = 0o755
+    os.chdir(str(tmpdir))
+    intermediate_dir = "тестовая-директория"
+    test_dir = os.path.join(intermediate_dir, "data")
+
+    assert not os.path.exists(intermediate_dir)
+
+    utils.makedirs(test_dir, mode=dir_mode)
+
+    assert stat.S_IMODE(os.stat(test_dir).st_mode) == dir_mode
+    assert stat.S_IMODE(os.stat(intermediate_dir).st_mode) == dir_mode
Repository: iterative/dvc
Issue: install: "Cask 'dvc' is not installed." error

Installed DVC 0.64.0 via pkg on MacOS:

```console
$ dvc version
DVC version: 0.64.0
Python version: 3.6.5
Platform: Darwin-19.0.0-x86_64-i386-64bit
Binary: True
Cache: reflink - True, hardlink - True, symlink - True
Filesystem type (cache directory): ('apfs', '/dev/disk1s5')
Filesystem type (workspace): ('apfs', '/dev/disk1s5')
```

Cloned and changed into the cloned iterative/example-get-started project, and ran dvc pull twice. Second run:

```dvc
$ dvc pull
Error: Cask 'dvc' is not installed.
+----------------------------------------------------------+
|                                                          |
|            Update available 0.64.0 -> 0.66.0             |
|                Find the latest release at                |
|     https://github.com/iterative/dvc/releases/latest     |
|                                                          |
+----------------------------------------------------------+

Everything is up to date.                                                                                                                                     
```

I realize this may be a fixed bug but just double checking it's not related to the updater.

Changed files:
dvc/updater.py, dvc/remote/s3.py

diff --git a/dvc/remote/s3.py b/dvc/remote/s3.py
index 169aee3ba..bd875c1c0 100644
--- a/dvc/remote/s3.py
+++ b/dvc/remote/s3.py
@@ -144,7 +144,7 @@ class RemoteS3(RemoteBASE):
         # multipart.
         #
         # If an object's etag looks like '8978c98bb5a48c2fb5f2c4c905768afa',
-        # then it was transfered as a single part, which means that the chunk
+        # then it was transferred as a single part, which means that the chunk
         # size used to transfer it was greater or equal to the ContentLength
         # of that object. So to preserve that tag over the next transfer, we
         # could use any value >= ContentLength.
diff --git a/dvc/updater.py b/dvc/updater.py
index 21251e4da..18625029f 100644
--- a/dvc/updater.py
+++ b/dvc/updater.py
@@ -123,7 +123,6 @@ class Updater(object):  # pragma: no cover
             "yum": "Run {yellow}yum{reset} update dvc",
             "yay": "Run {yellow}yay{reset} {blue}-S{reset} dvc",
             "formula": "Run {yellow}brew{reset} upgrade dvc",
-            "cask": "Run {yellow}brew cask{reset} upgrade dvc",
             "apt": (
                 "Run {yellow}apt-get{reset} install"
                 " {blue}--only-upgrade{reset} dvc"
@@ -169,14 +168,6 @@ class Updater(object):  # pragma: no cover
                 return "formula"
             else:
                 return "pip"
-
-        # NOTE: both pkg and cask put dvc binary into /usr/local/bin,
-        # so in order to know which method of installation was used,
-        # we need to actually call `brew cask`
-        ret = os.system("brew cask ls dvc")
-        if ret == 0:
-            return "cask"
-
         return None
 
     def _get_windows(self):
Repository: iterative/dvc
Issue: get/import: improve error message on no default remote

Since we allow importing/getting files that are not cached this error does not make much sense:

```
failed to import 'model.pkl' from '../test-import/'. - config file error: no remote specified. Setup default remote with
```

in a lot of cases.


Changed files:
dvc/external_repo.py, dvc/exceptions.py

diff --git a/dvc/exceptions.py b/dvc/exceptions.py
index 07a0ce806..291606614 100644
--- a/dvc/exceptions.py
+++ b/dvc/exceptions.py
@@ -328,3 +328,13 @@ class CheckoutError(DvcException):
 
 class CollectCacheError(DvcException):
     pass
+
+
+class RemoteNotSpecifiedInExternalRepoError(DvcException):
+    def __init__(self, url, cause=None):
+        super(RemoteNotSpecifiedInExternalRepoError, self).__init__(
+            "No DVC remote is specified in the target repository '{}'".format(
+                url
+            ),
+            cause=cause,
+        )
diff --git a/dvc/external_repo.py b/dvc/external_repo.py
index ccdadf6e6..874240bc7 100644
--- a/dvc/external_repo.py
+++ b/dvc/external_repo.py
@@ -7,6 +7,8 @@ from distutils.dir_util import copy_tree
 
 from funcy import retry
 
+from dvc.config import NoRemoteError
+from dvc.exceptions import RemoteNotSpecifiedInExternalRepoError
 from dvc.utils import remove
 
 
@@ -19,7 +21,10 @@ def external_repo(url=None, rev=None, rev_lock=None, cache_dir=None):
 
     path = _external_repo(url=url, rev=rev_lock or rev, cache_dir=cache_dir)
     repo = Repo(path)
-    yield repo
+    try:
+        yield repo
+    except NoRemoteError as exc:
+        raise RemoteNotSpecifiedInExternalRepoError(url, cause=exc)
     repo.close()
Repository: iterative/dvc
Issue: unknown encoding during "dvc push"

**Information about your setup**
DVC version: 0.66.0
Platform: Ubuntu 18.04
Method of installation: DEB

**Description:**
I access my dvc remote via ssh.  **Sometimes** `dvc push` command with the following error:

```
ERROR: unexpected error - unknown encoding: idna
```

Changed files:
dvc/main.py

diff --git a/dvc/main.py b/dvc/main.py
index 0c83ddab3..b18117f79 100644
--- a/dvc/main.py
+++ b/dvc/main.py
@@ -15,6 +15,12 @@ from dvc.remote.pool import close_pools
 from dvc.utils.compat import is_py2
 
 
+# Workaround for CPython bug. See [1] and [2] for more info.
+# [1] https://github.com/aws/aws-cli/blob/1.16.277/awscli/clidriver.py#L55
+# [2] https://bugs.python.org/issue29288
+"".encode("idna")
+
+
 logger = logging.getLogger("dvc")
Repository: iterative/dvc
Issue: dvc status regression after 0.33.1 release

I'm using OSX/Darwin.

All the checksums in my pipelines have changed starting from version 0.33.1.

Bug very similar to https://github.com/iterative/dvc/issues/1680

E.g: With a single file added with `dvc add helico_val.h5.dvc`:

###### dvc 0.32.1: OK ✅
```
$ pip install dvc==0.32.1
$ dvc status --show-checksums helico_val.h5.dvc
+-------------------------------------------+
|                                           |
|     Update available 0.32.1 -> 0.34.1     |
|       Run pip install dvc --upgrade       |
|                                           |
+-------------------------------------------+

Pipeline is up to date. Nothing to reproduce.
```

##### dvc 0.33.1: NOK ❌
```
$ pip install dvc==0.33.1
$ dvc status --show-checksums helico_val.h5.dvc
+-------------------------------------------+
|                                           |
|     Update available 0.33.1 -> 0.34.1     |
|       Run pip install dvc --upgrade       |
|                                           |
+-------------------------------------------+

helico_val.h5.dvc:
	changed checksum
```

##### dvc 0.34.1: NOK ❌
```
$ pip install dvc==0.34.1
$ dvc status --show-checksums helico_val.h5.dvc
helico_val.h5.dvc:
	changed checksum
```

I also did the check by computing the md5 sum with `md5 helico_val.h5` and it seems that the right version of the md5 is for version <= 0.32.1





Changed files:
tests/test_add.py, dvc/stage.py

diff --git a/dvc/stage.py b/dvc/stage.py
index 454ad838e..9c2252699 100644
--- a/dvc/stage.py
+++ b/dvc/stage.py
@@ -621,7 +621,7 @@ class Stage(object):
         self.repo.scm.track_file(os.path.relpath(fname))
 
     def _compute_md5(self):
-        from dvc.output.local import OutputLOCAL
+        from dvc.output.base import OutputBase
 
         d = self.dumpd()
 
@@ -643,8 +643,9 @@ class Stage(object):
             d,
             exclude=[
                 self.PARAM_LOCKED,
-                OutputLOCAL.PARAM_METRIC,
-                OutputLOCAL.PARAM_TAGS,
+                OutputBase.PARAM_METRIC,
+                OutputBase.PARAM_TAGS,
+                OutputBase.PARAM_PERSIST,
             ],
         )
         logger.debug("Computed stage '{}' md5: '{}'".format(self.relpath, m))
diff --git a/tests/test_add.py b/tests/test_add.py
index 995846d4a..cce7e260f 100644
--- a/tests/test_add.py
+++ b/tests/test_add.py
@@ -39,6 +39,7 @@ class TestAdd(TestDvc):
         self.assertEqual(len(stage.deps), 0)
         self.assertEqual(stage.cmd, None)
         self.assertEqual(stage.outs[0].info["md5"], md5)
+        self.assertEqual(stage.md5, "ee343f2482f53efffc109be83cc976ac")
 
     def test_unicode(self):
         fname = "\\xe1"
Repository: iterative/dvc
Issue: `dvc remote add` replaces the existing remote silently

The `dvc remote add` command ignores the existing remote and overwrites it silently. 
```
→ dvc --version
0.32.1+7d7ed4
```

### To reproduce

```bash
dvc remote add s3 s3://bucket/subdir
dvc remote add s3 s3://bucket/subdir2
```

### Expected behavior

The second command `dvc remote add s3 s3://bucket/subdir2` should fail with the `Remote with name "s3" already exists` message.

### Current behavior

Remote URL is silently overwriten:
```bash
> cat .dvc/config
['remote "s3"']
url = s3://bucket/subdir2
```

Changed files:
tests/test_remote.py, dvc/command/remote.py

diff --git a/dvc/command/remote.py b/dvc/command/remote.py
index fb03c536f..9bb487639 100644
--- a/dvc/command/remote.py
+++ b/dvc/command/remote.py
@@ -5,9 +5,9 @@ import os
 import re
 
 import dvc.logger as logger
-from dvc.command.base import fix_subparsers, append_doc_link
-from dvc.config import Config
+from dvc.command.base import append_doc_link, fix_subparsers
 from dvc.command.config import CmdConfig
+from dvc.config import Config
 
 
 class CmdRemoteAdd(CmdConfig):
@@ -39,6 +39,14 @@ class CmdRemoteAdd(CmdConfig):
             )
 
         section = Config.SECTION_REMOTE_FMT.format(self.args.name)
+        if (section in self.configobj.keys()) and not self.args.force:
+            logger.error(
+                "Remote with name {} already exists. "
+                "Use -f (--force) to overwrite remote "
+                "with new value".format(self.args.name)
+            )
+            return 1
+
         ret = self._set(section, Config.SECTION_REMOTE_URL, self.args.url)
         if ret != 0:
             return ret
@@ -156,6 +164,13 @@ def add_parser(subparsers, parent_parser):
         default=False,
         help="Set as default remote.",
     )
+    remote_add_parser.add_argument(
+        "-f",
+        "--force",
+        action="store_true",
+        default=False,
+        help="Force overwriting existing configs",
+    )
     remote_add_parser.set_defaults(func=CmdRemoteAdd)
 
     REMOTE_DEFAULT_HELP = "Set/unset default remote."
diff --git a/tests/test_remote.py b/tests/test_remote.py
index c2e611732..b298c092e 100644
--- a/tests/test_remote.py
+++ b/tests/test_remote.py
@@ -57,6 +57,15 @@ class TestRemote(TestDvc):
         config = configobj.ConfigObj(self.dvc.config.config_file)
         self.assertEqual(config['remote "mylocal"']["url"], rel)
 
+    def test_overwrite(self):
+        remote_name = "a"
+        remote_url = "s3://bucket/name"
+        self.assertEqual(main(["remote", "add", remote_name, remote_url]), 0)
+        self.assertEqual(main(["remote", "add", remote_name, remote_url]), 1)
+        self.assertEqual(
+            main(["remote", "add", "-f", remote_name, remote_url]), 0
+        )
+
 
 class TestRemoteRemoveDefault(TestDvc):
     def test(self):
Repository: iterative/dvc
Issue: Perf issue with large number of files

Tested with 25K files. We had a similar issue before.

Changed files:
dvc/remote/local.py

diff --git a/dvc/remote/local.py b/dvc/remote/local.py
index 7b887209f..0dd8e9ac6 100644
--- a/dvc/remote/local.py
+++ b/dvc/remote/local.py
@@ -144,7 +144,7 @@ class RemoteLOCAL(RemoteBase):
     def is_dir_cache(cache):
         return cache.endswith(State.MD5_DIR_SUFFIX)
 
-    def checkout(self, path_info, checksum_info, dump=True):
+    def checkout(self, path_info, checksum_info):
         path = path_info['path']
         md5 = checksum_info.get(self.PARAM_MD5, None)
         cache = self.get(md5)
@@ -162,7 +162,7 @@ class RemoteLOCAL(RemoteBase):
             remove(path)
 
         if not self.is_dir_cache(cache):
-            self.link(cache, path, dump=dump)
+            self.link(cache, path, dump=True)
             return
 
         msg = u'Checking out directory \\'{}\\' with cache \\'{}\\''
@@ -176,7 +176,8 @@ class RemoteLOCAL(RemoteBase):
         dir_cache = self.dir_cache(cache)
         for relpath, c in dir_cache.items():
             p = os.path.join(path, relpath)
-            self.link(c, p, dump=dump)
+            self.link(c, p, dump=False)
+        self.link_state.dump()
 
     def _move(self, inp, outp):
         # moving in two stages to make last the move atomic in
@@ -185,7 +186,7 @@ class RemoteLOCAL(RemoteBase):
         move(inp, tmp)
         move(tmp, outp)
 
-    def _save_file(self, path_info, dump=True):
+    def _save_file(self, path_info):
         path = path_info['path']
         md5 = self.state.update(path)
         cache = self.get(md5)
@@ -194,7 +195,6 @@ class RemoteLOCAL(RemoteBase):
                                                            os.path.relpath(cache)))
             self._move(path, cache)
             self.state.update(cache)
-        self.checkout(path_info, {self.PARAM_MD5: md5}, dump=dump)
 
         return {self.PARAM_MD5: md5}
 
@@ -209,8 +209,7 @@ class RemoteLOCAL(RemoteBase):
             relpath = entry[State.PARAM_RELPATH]
             p = os.path.join(path, relpath)
 
-            self._save_file({'scheme': 'local', 'path': p}, dump=False)
-        self.link_state.dump()
+            self._save_file({'scheme': 'local', 'path': p})
 
         if not os.path.isdir(dname):
             os.makedirs(dname)
@@ -230,9 +229,13 @@ class RemoteLOCAL(RemoteBase):
         path = path_info['path']
 
         if os.path.isdir(path):
-            return self._save_dir(path_info)
+            checksum_info = self._save_dir(path_info)
         else:
-            return self._save_file(path_info)
+            checksum_info = self._save_file(path_info)
+
+        self.checkout(path_info, checksum_info)
+
+        return checksum_info
 
     def save_info(self, path_info):
         if path_info['scheme'] != 'local':
Repository: iterative/dvc
Issue: run: automatic dvcfile name generation for directories

When -f not specified and -o is a directory and --cwd is specified, `dvc run` generates wrong fname for the resulting dvcfile.

Kudos @Nicolabo for discovering!

Changed files:
dvc/command/run.py

diff --git a/dvc/command/run.py b/dvc/command/run.py
index b2fec20f6..de6ffc82e 100644
--- a/dvc/command/run.py
+++ b/dvc/command/run.py
@@ -43,6 +43,6 @@ class CmdRun(CmdBase):
     def _stage_file_basename(fname):
         result = os.path.basename(fname)
         if len(result) == 0:
-            result = os.path.dirname(fname)
+            result = os.path.basename(os.path.dirname(fname))
         result += Stage.STAGE_FILE_SUFFIX
         return result
Repository: iterative/dvc
Issue: dvc run messes up library paths

I have a command that relies on `cupy`. When I run it with `dvc run ...`, it raises this error and fails:
```bash
/tmp/_MEIeW2y4B/libstdc++.so.6: version `GLIBCXX_3.4.20' not found
```
If I run it without `dvc run`, no error is raised. I think this is b/c dvc run uses `p = subprocess.Popen(self.cmd, cwd=self.cwd, shell=True)` and it's messing up the environment variables. Would passing in the environment variables solve this problem?
```python
env = os.environ
proc = subprocess.Popen(args, env=env)
```

Changed files:
tests/test_repro.py, dvc/stage.py

diff --git a/dvc/stage.py b/dvc/stage.py
index 86e5f5ab7..d5a926e5f 100644
--- a/dvc/stage.py
+++ b/dvc/stage.py
@@ -226,7 +226,11 @@ class Stage(object):
         if not self.is_data_source:
             self.project.logger.info(u'Reproducing \\'{}\\':\\n\\t{}'.format(self.relpath, self.cmd))
 
-            p = subprocess.Popen(self.cmd, cwd=self.cwd, shell=True)
+            p = subprocess.Popen(self.cmd,
+                                 cwd=self.cwd,
+                                 shell=True,
+                                 env=os.environ,
+                                 executable=os.getenv('SHELL'))
             p.communicate()
             if p.returncode != 0:
                raise StageCmdFailedError(self)
diff --git a/tests/test_repro.py b/tests/test_repro.py
index 9ee5d052e..3b9b2ce16 100644
--- a/tests/test_repro.py
+++ b/tests/test_repro.py
@@ -297,3 +297,26 @@ class TestReproExternalGS(TestReproExternalBase):
         client = gc.Client()
         bucket = client.bucket(bucket)
         bucket.blob(key).upload_from_string(body)
+
+
+class TestReproShell(TestDvc):
+    def test(self):
+        if os.name == 'nt':
+            return
+
+        fname = 'shell.txt'
+        stage = fname + '.dvc'
+
+        self.dvc.run(fname=stage,
+                     outs=[fname],
+                     cmd='echo $SHELL > {}'.format(fname))
+
+        with open(fname, 'r') as fd:
+            self.assertEqual(os.getenv('SHELL'), fd.read().strip())
+
+        os.unlink(fname)
+
+        self.dvc.reproduce(stage)
+
+        with open(fname, 'r') as fd:
+            self.assertEqual(os.getenv('SHELL'), fd.read().strip())
Repository: iterative/dvc
Issue: DVC repro is reproducing unchanged stages

Hey guys, I noticed that DVC repro reproduces unnecessary stages (version 0.9.7 from pip): 

```bash
# Initialize GIT and DVC repository
git init
dvc init
git add .dvc

# Create example folder
mkdir example
cd example

# Create hello.txt
dvc run -o hello.txt 'yes "Hello" | head -10 > hello.txt'
## Using 'hello.txt.dvc' as a stage file
## Reproducing 'hello.txt.dvc':
## 	yes "Hello" | head -10 > hello.txt

# Create world.txt
dvc run -o world.txt 'yes "World" | head -10 > world.txt'
## Using 'world.txt.dvc' as a stage file
## Reproducing 'world.txt.dvc':
## 	yes "World" | head -10 > world.txt

# Merge into hello_world.txt
dvc run -d hello.txt -d world.txt -o hello_world.txt 'paste hello.txt world.txt > hello_world.txt'
## Using 'hello_world.txt.dvc' as a stage file
## Reproducing 'hello_world.txt.dvc':
## 	paste hello.txt world.txt > hello_world.txt

dvc status
## (No changes)

dvc repro hello_world.txt.dvc
## Reproducing 'hello.txt.dvc':
## 	yes "Hello" | head -10 > hello.txt
## Reproducing 'world.txt.dvc':
## 	yes "World" | head -10 > world.txt
```

Is this expected behavior?

Changed files:
dvc/stage.py

diff --git a/dvc/stage.py b/dvc/stage.py
index d5a926e5f..d1f658526 100644
--- a/dvc/stage.py
+++ b/dvc/stage.py
@@ -91,10 +91,14 @@ class Stage(object):
         self.project.logger.debug(msg.format(self.relpath, self.md5, md5))
         return True
 
+    @property
+    def is_callback(self):
+        return not self.is_data_source and len(self.deps) == 0
+
     def changed(self):
         ret = False
 
-        if not self.is_data_source and len(self.deps) == 0:
+        if self.is_callback:
             ret = True
 
         for entry in itertools.chain(self.outs, self.deps):
@@ -268,7 +272,7 @@ class Stage(object):
         ret.update(self._status(self.deps, 'deps'))
         ret.update(self._status(self.outs, 'outs'))
 
-        if ret or self.changed_md5():
+        if ret or self.changed_md5() or self.is_callback:
             return {self.relpath: ret}
 
         return {}
Repository: iterative/dvc
Issue: dvc remote without a command throws an error

```
$ dvc remote
Initialization error: 'Namespace' object has no attribute 'func'
```
It should probably print out help instead.

Changed files:
dvc/cli.py

diff --git a/dvc/cli.py b/dvc/cli.py
index b40c51ed1..97d0c0f3f 100644
--- a/dvc/cli.py
+++ b/dvc/cli.py
@@ -23,6 +23,16 @@ from dvc.stage import Stage
 from dvc import VERSION
 
 
+def _fix_subparsers(subparsers):
+    # NOTE: Workaround for bug in Python 3
+    # More info at:
+    #  https://bugs.python.org/issue16308
+    #  https://github.com/iterative/dvc/issues/769
+    if sys.version_info[0] == 3:
+        subparsers.required = True
+        subparsers.dest = 'cmd'
+
+
 def parse_args(argv=None):
     # Common args
     parent_parser = argparse.ArgumentParser(add_help=False)
@@ -58,10 +68,7 @@ def parse_args(argv=None):
                         dest='cmd',
                         help='Use dvc CMD --help for command-specific help')
 
-    # NOTE: Workaround for bug in Python 3
-    if sys.version_info[0] == 3:
-        subparsers.required = True
-        subparsers.dest = 'cmd'
+    _fix_subparsers(subparsers)
 
     # Init
     init_parser = subparsers.add_parser(
@@ -283,6 +290,8 @@ def parse_args(argv=None):
                         dest='cmd',
                         help='Use dvc remote CMD --help for command-specific help')
 
+    _fix_subparsers(remote_subparsers)
+
     remote_add_parser = remote_subparsers.add_parser(
                         'add',
                         parents=[parent_parser],
Repository: iterative/dvc
Issue: 'dvc add' fails on files encoded in Latin-1

Running 'dvc add TEXTFILE' fails if TEXTFILE is encoded in Latin-1. The following error message is shown: 

Unexpected error: 'utf8' codec can't decode byte 0xa3 in position 12204: invalid start byte

The error disapears if TEXTFILE is saved with encoding UTF-8 before running 'dvc add'. So does dvc only support files encoded in UTF-8?

Changed files:
dvc/utils.py, tests/test_utils.py

diff --git a/dvc/utils.py b/dvc/utils.py
index ea4ba37da..cd724cde5 100644
--- a/dvc/utils.py
+++ b/dvc/utils.py
@@ -20,7 +20,7 @@ LOCAL_CHUNK_SIZE = 1024*1024
 
 
 def dos2unix(data):
-    return '\\n'.join(data.split('\\r\\n'))
+    return data.replace(b'\\r\\n', b'\\n')
 
 
 def file_md5(fname):
@@ -35,12 +35,7 @@ def file_md5(fname):
         else:
             binary = is_binary(fname)
 
-        if binary:
-            mode = "rb"
-        else:
-            mode = "r"
-
-        with open(fname, mode) as fobj:
+        with open(fname, 'rb') as fobj:
             while True:
                 data = fobj.read(LOCAL_CHUNK_SIZE)
                 if not data:
@@ -49,9 +44,7 @@ def file_md5(fname):
                 if binary:
                     chunk = data
                 else:
-                    if sys.version_info[0] == 2:
-                        data = data.decode('utf-8')
-                    chunk = dos2unix(data).encode('utf-8')
+                    chunk = dos2unix(data)
 
                 hash_md5.update(chunk)
 
diff --git a/tests/test_utils.py b/tests/test_utils.py
index b1344d89c..4b4527474 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -37,3 +37,11 @@ class TestUtils(TestDvc):
 
         for n in n_threads:
             utils.map_progress(f, targets, n)
+
+    def test_file_md5_crlf(self):
+        with open('cr', 'wb+') as fd:
+            fd.write(b'a\\nb\\nc')
+        with open('crlf', 'wb+') as fd:
+            fd.write(b'a\\r\\nb\\r\\nc')
+
+        self.assertEqual(utils.file_md5('cr')[0], utils.file_md5('crlf')[0])
Repository: iterative/dvc
Issue: Checkout single file when pulling single file

Hi guys, I noticed `self.checkout()` of whole project is performed even when pulling single target, is this expected behavior? I would expect `self.checkout(target=target)`.

Cheers,
David

Changed files:
dvc/project.py

diff --git a/dvc/project.py b/dvc/project.py
index 5ff040676..3ffef039b 100644
--- a/dvc/project.py
+++ b/dvc/project.py
@@ -295,7 +295,7 @@ class Project(object):
 
     def pull(self, target=None, jobs=1, remote=None, all_branches=False):
         self.fetch(target, jobs, remote=remote, all_branches=all_branches)
-        self.checkout()
+        self.checkout(target=target)
 
     def _local_status(self, target=None):
         status = {}
Repository: iterative/dvc
Issue: dvc init fails if repository has files marked with --skip-worktree

Using dvc 0.9.3, running `dvc init` will yield `Unexpected Error: ` (but creates the `.dvc` directory anyway).

Observed in Python 3.6 on Windows and Python 3.5 on WSL (Ubuntu) - both installed from PyPI.

Changed files:
dvc/scm.py

diff --git a/dvc/scm.py b/dvc/scm.py
index 34d11d444..ecced4059 100644
--- a/dvc/scm.py
+++ b/dvc/scm.py
@@ -1,6 +1,7 @@
 import os
 
 from dvc.exceptions import DvcException
+from dvc.logger import Logger
 
 
 class SCMError(DvcException):
@@ -131,7 +132,14 @@ class Git(Base):
             fd.writelines(filtered)
 
     def add(self, paths):
-        self.repo.index.add(paths)
+        # NOTE: GitPython is not currently able to handle index version >= 3.
+        # See https://github.com/iterative/dvc/issues/610 for more details.
+        try:
+            self.repo.index.add(paths)
+        except AssertionError as exc:
+            msg = 'Failed to add \\'{}\\' to git. You can add those files manually using \\'git add\\'. '
+            msg += 'See \\'https://github.com/iterative/dvc/issues/610\\' for more details.'
+            Logger.error(msg.format(str(paths)), exc)
 
     def commit(self, msg):
         self.repo.index.commit(msg)
Repository: iterative/dvc
Issue: Locked warning is shown for all files in dvc status

Hi there, the *locked file* warning seems to be shown for all files in dvc status:

```
git init
dvc init
git add .dvc 

# Create example folder
mkdir example
cd example

# Create hello.txt and world.txt
dvc run -o hello.txt 'yes "Hello" | head -10 > hello.txt'
dvc run -o world.txt 'yes "World" | head -10 > world.txt'

# Merge into hello_world.txt
dvc run -d hello.txt -d world.txt -o hello_world.txt 'paste hello.txt world.txt > hello_world.txt'

## Running command:
## 	yes "Hello" | head -10 > hello.txt
## Running command:
## 	yes "World" | head -10 > world.txt
## Running command:
## 	paste hello.txt world.txt > hello_world.txt

dvc status
## DVC file 'hello.txt.dvc' is locked. Its dependecies are not going to be shown in status output.
## DVC file 'world.txt.dvc' is locked. Its dependecies are not going to be shown in status output.
## DVC file 'hello_world.txt.dvc' is locked. Its dependecies are not going to be shown in status output.
## hello.txt.dvc
## world.txt.dvc

cat hello_world.txt.dvc 
## cmd: paste hello.txt world.txt > hello_world.txt
## deps:
## - md5: 2b360db687b5870bd328adbb56d3bf8f
##   path: hello.txt
## - md5: 53d23c8121564867f8ee222841a83811
##   path: world.txt
## md5: e1e60249c4f84c11cda133706d649e31
## outs:
## - cache: true
##   md5: 1abddce536be836e612dedc0a272b86f
##   metric: false
##   path: hello_world.txt
```

Changed files:
dvc/project.py

diff --git a/dvc/project.py b/dvc/project.py
index 03e082364..e9ccd2169 100644
--- a/dvc/project.py
+++ b/dvc/project.py
@@ -362,7 +362,7 @@ class Project(object):
             stages = self.active_stages()
 
         for stage in stages:
-            if not stage.locked:
+            if stage.locked:
                 msg = 'DVC file \\'{}\\' is locked. Its dependecies are not ' \\
                       'going to be shown in status output.'
                 self.logger.warn(msg.format(stage.relpath))
Repository: iterative/dvc
Issue: Trouble installing dvc with pip: No matching distribution found for futures>=3.2.0 (from dvc)

I'm on a fresh ubuntu 18.04 and I want to install DVC. But I run into some dependency problems. Never had that problem before.
```
➤ virtualenv -p python3 .venv
➤ source .venv/bin/activate.fish
➤ pip install dvc
Collecting dvc
  Using cached https://files.pythonhosted.org/packages/d2/2d/117b6e99f4e7f0760d99944919d9dcaaeabfb6c6182a9c890b7260eec697/dvc-0.15.2-py2.py3-none-any.whl
Collecting pyasn1>=0.4.1 (from dvc)
  Using cached https://files.pythonhosted.org/packages/d1/a1/7790cc85db38daa874f6a2e6308131b9953feb1367f2ae2d1123bb93a9f5/pyasn1-0.4.4-py2.py3-none-any.whl
Collecting ply>=3.9 (from dvc)
  Using cached https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl
Collecting futures>=3.2.0 (from dvc)
  Could not find a version that satisfies the requirement futures>=3.2.0 (from dvc) (from versions: 0.2.python3, 0.1, 0.2, 1.0, 2.0, 2.1, 2.1.1, 2.1.2, 2.1.3, 2.1.4, 2.1.5, 2.1.6, 2.2.0, 3.0.0, 3.0.1, 3.0.2, 3.0.3, 3.0.4, 3.0.5, 3.1.0, 3.1.1)
No matching distribution found for futures>=3.2.0 (from dvc)
```
Here are all relevant version
```
➤ pip --version
pip 18.0 from /home/PATH/.venv/lib/python3.6/site-packages/pip (python 3.6)
➤ python --version
Python 3.6.5
➤ virtualenv --version
16.0.0
```

Changed files:
setup.py

diff --git a/setup.py b/setup.py
index 97eb7e198..7a15f6ed0 100644
--- a/setup.py
+++ b/setup.py
@@ -23,11 +23,9 @@ install_requires = [
     "jsonpath-rw==1.4.0",
     "reflink==0.2.0",
     "requests>=2.18.4",
+    'futures; python_version == "2.7"',
 ]
 
-if sys.version_info[0] == 2:
-    install_requires.append("futures>=3.2.0")
-
 # Extra dependencies for remote integrations
 gs = [
     "google-cloud==0.32.0",
Repository: iterative/dvc
Issue: `dvc pipeline show` wrong usage message when no target is specified

To reproduce run:

`dvc pipeline show`

It's printing DVC's general usage while it should be printing:

```usage: dvc pipeline show [-h] [-q] [-v] [-c | -o] [--ascii]
                         [targets [targets ...]]

Show pipeline.

positional arguments:
  targets         DVC files. 'Dvcfile' by default.

optional arguments:
  -h, --help      show this help message and exit
  -q, --quiet     Be quiet.
  -v, --verbose   Be verbose.
  -c, --commands  Print commands instead of paths to DVC files.
  -o, --outs      Print output files instead of paths to DVC files.
  --ascii         Output DAG as ASCII.
```



Changed files:
dvc/cli.py

diff --git a/dvc/cli.py b/dvc/cli.py
index 922762e55..b8b04be72 100644
--- a/dvc/cli.py
+++ b/dvc/cli.py
@@ -785,7 +785,11 @@ def parse_args(argv=None):
             cwd = os.curdir
         path = os.path.join(cwd, 'Dvcfile')
         if not os.path.exists(path):
-            parser.error("default target '{}' does not exist.".format(path))
+            msg = "default target '{}' does not exist.".format(path)
+            if issubclass(args.func, CmdRepro):
+                repro_parser.error(msg)
+            elif issubclass(args.func, CmdPipelineShow):
+                pipeline_show_parser.error(msg)
         args.targets = ['Dvcfile']
 
     return args
Repository: iterative/dvc
Issue: Custom credentialpath not working

Credentialpath is not working with the following config:

```
[core]
remote = models
cloud = AWS
['remote "models"']
url = s3://<bucket-name>
credentialpath = /home/ubuntu/Models/.dvc/aws_credentials
```

Works with the default path:

`credentialpath = /home/ubuntu/.aws/credentials`

The credentials files are identical.

Setup:

DVC: 0.17.0
Installation: pip3 install dvc[all]
OS: Ubuntu 16.04.4

Changed files:
dvc/remote/s3.py

diff --git a/dvc/remote/s3.py b/dvc/remote/s3.py
index 5e07abc88..5f60b35e4 100644
--- a/dvc/remote/s3.py
+++ b/dvc/remote/s3.py
@@ -57,6 +57,7 @@ class RemoteS3(RemoteBase):
         else:
             creds = {}
 
+        self.creds = creds
         self.region = creds.get('region', self.region)
         self.aws_access_key_id = creds.get('aws_access_key_id', None)
         self.aws_secret_access_key = creds.get('aws_secret_access_key', None)
@@ -71,12 +72,14 @@ class RemoteS3(RemoteBase):
 
     @property
     def s3(self):
-        session = boto3.session.Session(profile_name=self.profile)
-        return session.client('s3',
-                              aws_access_key_id=self.aws_access_key_id,
-                              aws_secret_access_key=self.aws_secret_access_key,
-                              region_name=self.region,
-                              endpoint_url=self.endpoint_url)
+        if not self.creds:
+            session = boto3.session.Session(profile_name=self.profile)
+        else:
+            session = boto3.session.Session(
+                             aws_access_key_id=self.aws_access_key_id,
+                             aws_secret_access_key=self.aws_secret_access_key,
+                             region_name=self.region)
+        return session.client('s3', endpoint_url=self.endpoint_url)
 
     def get_etag(self, bucket, key):
         try:
Repository: iterative/dvc
Issue: Terminal encoding and `dvc run`

@dmpetrov discovered an issue with `dvc run` when it throws an error(same w/o -v):
```
Unexpected error: 'ascii' codec can't decode byte 0xef in position 137272: ordinal not in range(128)
```

Adding 
```
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
```
helps.

Probably just python2 problem, as python3 uses utf8 by default instead of ascii.

Changed files:
dvc/utils.py

diff --git a/dvc/utils.py b/dvc/utils.py
index 86f8fdd4e..debce3ec2 100644
--- a/dvc/utils.py
+++ b/dvc/utils.py
@@ -3,6 +3,7 @@ Helpers for other modules.
 """
 import os
 import re
+import sys
 import json
 import stat
 import shutil
@@ -41,6 +42,8 @@ def file_md5(fname):
                 if binary:
                     chunk = data
                 else:
+                    if sys.version_info[0] == 2:
+                        data = data.decode('utf-8')
                     chunk = dos2unix(data).encode('utf-8')
 
                 hash_md5.update(chunk)
Repository: iterative/dvc
Issue: DVC pull fails on unstaged files when running in subdirectory

Hi, I noticed `dvc pull` fails when I run it inside a subdirectory and some unstaged files are present.

How to reproduce:
```
git init
dvc init
dvc config Core.Cloud AWS
dvc config AWS.StoragePath dvc-example-bucket/cache
git add .dvc

mkdir example
cd example

echo "Hello World" > hello.txt
dvc add hello.txt

git add .

touch other.txt

dvc push
# (1/1): [##############################] 100% e5/9ff97941044f85df5297e1c302d260

# Fails:
dvc pull hello.txt.dvc
# Failed to pull data from the cloud: [Errno 2] No such file or directory: 'example/other.txt'

# Running from parent directory works.
cd ..
dvc pull example/hello.txt.dvc
```

Changed files:
dvc/scm.py

diff --git a/dvc/scm.py b/dvc/scm.py
index 606359c02..79a7572c7 100644
--- a/dvc/scm.py
+++ b/dvc/scm.py
@@ -137,7 +137,8 @@ class Git(Base):
         self.repo.git.branch(branch)
 
     def untracked_files(self):
-        return self.repo.untracked_files
+        files = self.repo.untracked_files
+        return [os.path.join(self.repo.working_dir, fname) for fname in files]
 
     def is_tracked(self, path):
         return len(self.repo.git.ls_files(path)) != 0
Repository: iterative/dvc
Issue: dvc repro after merge

`dvc repro` rerun command after merge if data files were generated in different branches.

Please take a look at `functest/tutorial_branches.sh` from beginning to line 61. In theory, in this line only steps after `Posts.tsv` should be reproduced.

Changed files:
dvc/command/repro.py

diff --git a/dvc/command/repro.py b/dvc/command/repro.py
index 16b7f1763..990cbb953 100644
--- a/dvc/command/repro.py
+++ b/dvc/command/repro.py
@@ -85,6 +85,7 @@ class CmdRepro(CmdRun):
                     continue
 
                 globally_changed_files = self.git.get_changed_files(target_commit)
+                Logger.debug('Repro globally changed files: {}'.format(', '.join(globally_changed_files)))
                 changed_files = set()
                 change = ReproChange(data_item, self, globally_changed_files, recursive, force)
                 if change.reproduce(changed_files):
@@ -244,9 +245,13 @@ class ReproChange(object):
                 Logger.debug(u'Repro data item {}: dependency {} was changed'.format(
                     data_item_dvc, data_item.data.dvc))
             elif data_item.state.dvc in self._globally_changed_files:
-                msg = u'Repro data item {}: dependency {} was not changed but the state file was changed'
-                Logger.debug(msg.format(data_item_dvc, data_item.data.dvc))
-                result = True
+                dep_state = StateFile.load(data_item, self._settings)
+                if dep_state.command != StateFile.COMMAND_IMPORT_FILE:
+                    msg = u'Repro data item {}: dependency {} was not changed but the state file was changed'
+                    Logger.debug(msg.format(data_item_dvc, data_item.data.dvc))
+                    result = True
+                else:
+                    Logger.debug(u'Repro data item {}: skip dependency state file change {} due to data source command')
             else:
                 msg = u'Repro data item {}: dependency {} was not changed'
                 Logger.debug(msg.format(data_item_dvc, data_item.data.dvc))
Repository: iterative/dvc
Issue: Sync cmd: 1/10 num prefix

The num prefix is constantly equal to 1/10.

```$ dvc sync data/
(1/10): [####################################### ] 99% model.p_51b6e1a
```

Changed files:
dvc/data_cloud.py

diff --git a/dvc/data_cloud.py b/dvc/data_cloud.py
index 6946c3330..c8630a9d8 100644
--- a/dvc/data_cloud.py
+++ b/dvc/data_cloud.py
@@ -248,6 +248,7 @@ class DataCloudAWS(DataCloudBase):
         Logger.info('Downloading cache file from S3 "{}/{}"'.format(bucket.name, key_name))
         key.get_contents_to_filename(item.resolved_cache.relative,
                                      cb=create_cb(item.resolved_cache.relative))
+        progress.finish_target(os.path.basename(item.resolved_cache.relative))
         Logger.info('Downloading completed')
 
     def sync_to_cloud(self, data_item):
@@ -270,6 +271,7 @@ class DataCloudAWS(DataCloudBase):
         key = bucket.new_key(aws_key)
         key.set_contents_from_filename(data_item.resolved_cache.relative,
                                        cb=create_cb(data_item.resolved_cache.relative))
+        progress.finish_target(os.path.basename(data_item.resolved_cache.relateive))
 
     def remove_from_cloud(self, data_item):
         aws_file_name = self.cache_file_key(data_item.cache.dvc)
Repository: iterative/dvc
Issue: Unconfigured git error

Git repository might be created but git might be not configured.
The results of this failure:
1. .gitignore file was not created.
2. change was not committed

```
c:\\src\\tmp>dvc init
Directories data/, .cache/ and .state/ were created
Error. Git command error (git commit -m DVC init. data dir data, cache dir .cache, state dir .state):
*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: empty ident name (for <(NULL)>) not allowed
```

Changed files:
dvc/git_wrapper.py

diff --git a/dvc/git_wrapper.py b/dvc/git_wrapper.py
index f466db785..4cc5d5e32 100644
--- a/dvc/git_wrapper.py
+++ b/dvc/git_wrapper.py
@@ -46,6 +46,15 @@ class GitWrapperI(object):
 
         return GitWrapper.parse_porcelain_files(out)
 
+    @staticmethod
+    def git_config_get(name):
+        code, out, err = Executor.exec_cmd(['git', 'config', '--get', name])
+        Logger.debug('[dvc-git] "git config --get {}": code({}), out({}), err({})'.format(
+                                                               name, code, out, err))
+        if code != 0:
+            return None
+        return out
+
     @staticmethod
     def git_path_to_system_path(path):
         if os.name == 'nt':
@@ -86,6 +95,17 @@ class GitWrapper(GitWrapperI):
                 Logger.error("{} {}".format(status, file))
             return False
 
+        # Sanity check to make sure we will be able to commit
+        name = self.git_config_get('user.name')
+        if name == None:
+            Logger.error('[dvc-git] Please setup user.name in git config')
+            return False
+
+        email = self.git_config_get('user.email')
+        if email == None:
+            Logger.error('[dvc-git] Please setup user.email in git config')
+            return False
+
         return True
 
     @property
Repository: iterative/dvc
Issue: Consistently getting broken pipe when syncing (uploading) large file

traceback (most recent call last):
 ```
 File "/Users/ophir/anaconda3/envs/p2/bin/dvc", line 11, in <module>
    sys.exit(main())
  File "/Users/ophir/anaconda3/envs/p2/lib/python2.7/site-packages/dvc/main.py", line 63, in main
    Runtime.run(CmdDataSync)
  File "/Users/ophir/anaconda3/envs/p2/lib/python2.7/site-packages/dvc/runtime.py", line 41, in run
    sys.exit(instance.run())
  File "/Users/ophir/anaconda3/envs/p2/lib/python2.7/site-packages/dvc/command/data_sync.py", line 47, in run
    pool.map(cloud.sync, targets)
  File "/Users/ophir/anaconda3/envs/p2/lib/python2.7/multiprocessing/pool.py", line 251, in map
    return self.map_async(func, iterable, chunksize).get()
  File "/Users/ophir/anaconda3/envs/p2/lib/python2.7/multiprocessing/pool.py", line 567, in get
    raise self._value
socket.error: [Errno 32] Broken pipe
```


p.s. 
is syncing the file manually using the aws cli a viable workaround, or are there other things done during the sync (updating status file or something similar)

Changed files:
dvc/data_cloud.py

diff --git a/dvc/data_cloud.py b/dvc/data_cloud.py
index c79c0e186..0d5695843 100644
--- a/dvc/data_cloud.py
+++ b/dvc/data_cloud.py
@@ -7,6 +7,7 @@ import tempfile
 import requests
 import configparser
 import filecmp
+import math
 
 from boto.s3.connection import S3Connection
 from google.cloud import storage as gc
@@ -455,6 +456,28 @@ class DataCloudAWS(DataCloudBase):
 
         return data_item
 
+    def _push_multipart(self, b, aws_key, fname):
+        mp = b.initiate_multipart_upload(aws_key)
+
+        source_size = os.stat(fname).st_size
+        chunk_size = 5000*1024*1024
+        chunk_count = int(math.ceil(source_size / float(chunk_size)))
+
+        with open(fname, 'r') as fp:
+            for i in range(chunk_count):
+                offset = i * chunk_size
+                left = source_size - offset
+                size = min([chunk_size, left])
+                part_num = i + 1
+
+                fp.seek(offset)
+                mp.upload_part_from_file(fp=fp, part_num=part_num, size=size, cb=create_cb(fname))
+
+        if len(mp.get_all_parts()) != chunk_count:
+            raise Exception("Couldn't upload all file parts")
+
+        mp.complete_upload()
+
     def push(self, data_item):
         """ push, aws version """
 
@@ -473,8 +496,7 @@ class DataCloudAWS(DataCloudBase):
         key = bucket.new_key(aws_key)
 
         try:
-            key.set_contents_from_filename(data_item.resolved_cache.relative,
-                                       cb=create_cb(data_item.resolved_cache.relative))
+            self._push_multipart(bucket, aws_key, data_item.resolved_cache.relative)
         except Exception as exc:
             Logger.error('Failed to upload "{}": {}'.format(data_item.resolved_cache.relative, exc))
             return None
Repository: iterative/dvc
Issue: Running DVC outside of Git dir

We should handle all the cases like this.

```
cd /
$ dvc repro
No handlers could be found for logger "dvc"
```

Changed files:
dvc/main.py, dvc/logger.py

diff --git a/dvc/logger.py b/dvc/logger.py
index d277aff97..893736ad2 100644
--- a/dvc/logger.py
+++ b/dvc/logger.py
@@ -25,15 +25,19 @@ class Logger(object):
     }
 
     def __init__(self, config=None):
+        self.init(config)
+
+    @staticmethod
+    def init(config=None):
         sh = logging.StreamHandler(sys.stdout)
-        sh.setFormatter(logging.Formatter(self.FMT))
+        sh.setFormatter(logging.Formatter(Logger.FMT))
         sh.setLevel(logging.DEBUG)
 
-        self.logger().addHandler(sh)
+        Logger.logger().addHandler(sh)
         level = None
         if config:
             level = config['Global'].get('LogLevel', None)
-        self.set_level(level)
+        Logger.set_level(level)
 
     @staticmethod
     def logger():
diff --git a/dvc/main.py b/dvc/main.py
index afc0f0be5..76deb4bd9 100644
--- a/dvc/main.py
+++ b/dvc/main.py
@@ -2,6 +2,8 @@ from dvc.logger import Logger
 from dvc.cli import parse_args
 
 def main(argv=None):
+    Logger.init()
+
     args = parse_args(argv)
 
     try:
Repository: iterative/dvc
Issue: Output format: do not print empty lines

Some of the commands print empty lines.

```
$ dvc pull # Nothing to pull
# This is an empty line
```

```
$ dvc status # Nothing to show
# This is an empty line
```

Probably we have more commands with the same issue.

Changed files:
dvc/utils.py, dvc/progress.py

diff --git a/dvc/progress.py b/dvc/progress.py
index 64ea7ed95..a40ba83f8 100644
--- a/dvc/progress.py
+++ b/dvc/progress.py
@@ -47,10 +47,6 @@ class Progress(object):
 
             self._n_finished += 1
 
-    def finish(self):
-        if sys.stdout.isatty():
-            print()
-
     def _bar(self, target_name, current, total):
         """
         Make a progress bar out of info, which looks like:
diff --git a/dvc/utils.py b/dvc/utils.py
index d0c707a14..7995c856b 100644
--- a/dvc/utils.py
+++ b/dvc/utils.py
@@ -129,7 +129,5 @@ def map_progress(func, targets, n_threads):
         ret = pool.map(wrapper, targets)
     except Exception as exc:
         raise
-    finally:
-        progress.finish()
 
     return list(zip(targets, ret))