internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: iterative/dvc

Issue:
md5: print a msg when computing md5 for a large file
Computing md5s for files bigger than a few GB takes some pretty noticeable time(the amount depends on the machine of course). Need to print some msg or even a progress bar to keep the user posted.


Discussion:

Resolving patch:
diff --git a/dvc/progress.py b/dvc/progress.py
--- a/dvc/progress.py
+++ b/dvc/progress.py
@@ -63,7 +63,10 @@ def _bar(self, target_name, current, total):
             progress = int((100 * current)/total) if current < total else 100
             percent = str(progress) + "% "
 
-        num = "({}/{}): ".format(self._n_finished + 1, self._n_total)
+        if self._n_total:
+            num = "({}/{}): ".format(self._n_finished + 1, self._n_total)
+        else:
+            num = ""
 
         n_sh = int((progress * bar_len)/100)
         n_sp = bar_len - n_sh
diff --git a/dvc/utils.py b/dvc/utils.py
--- a/dvc/utils.py
+++ b/dvc/utils.py
@@ -7,12 +7,13 @@
 import shutil
 import hashlib
 
-from dvc.istextfile import istextfile
 from dvc.progress import progress
+from dvc.istextfile import istextfile
 from dvc.logger import Logger
 
 
 LOCAL_CHUNK_SIZE = 1024*1024
+LARGE_FILE_SIZE = 1024*1024*1024
 
 
 def dos2unix(data):
@@ -24,6 +25,14 @@ def file_md5(fname):
     if os.path.exists(fname):
         hash_md5 = hashlib.md5()
         binary = not istextfile(fname)
+        size = os.path.getsize(fname)
+        bar = False
+        if size >= LARGE_FILE_SIZE:
+            bar = True
+            msg = "Computing md5 for a large file {}. This is only done once."
+            Logger.info(msg.format(os.path.relpath(fname)))
+            name = os.path.relpath(fname)
+            total = 0
 
         with open(fname, 'rb') as fobj:
             while True:
@@ -31,6 +40,10 @@ def file_md5(fname):
                 if not data:
                     break
 
+                if bar:
+                    total += len(data)
+                    progress.update_target(name, total, size)
+
                 if binary:
                     chunk = data
                 else:
@@ -38,6 +51,9 @@ def file_md5(fname):
 
                 hash_md5.update(chunk)
 
+        if bar:
+            progress.finish_target(name)
+
         return (hash_md5.hexdigest(), hash_md5.digest())
     else:
         return (None, None)


Test patch:
Repository: iterative/dvc

Issue:
Add confirmation prompt when trying to overwrite existing dvc file



Discussion:

Resolving patch:
diff --git a/dvc/project.py b/dvc/project.py
--- a/dvc/project.py
+++ b/dvc/project.py
@@ -218,7 +218,8 @@ def run(self,
                             outs=outs,
                             outs_no_cache=outs_no_cache,
                             metrics_no_cache=metrics_no_cache,
-                            deps=deps)
+                            deps=deps,
+                            overwrite=False)
         if not no_exec:
             stage.run()
         stage.dump()
diff --git a/dvc/stage.py b/dvc/stage.py
--- a/dvc/stage.py
+++ b/dvc/stage.py
@@ -8,6 +8,7 @@
 import dvc.dependency as dependency
 import dvc.output as output
 from dvc.exceptions import DvcException
+from dvc.prompt import prompt
 from dvc.logger import Logger
 from dvc.utils import dict_md5
 
@@ -227,7 +228,8 @@ def loads(project=None,
               fname=None,
               cwd=os.curdir,
               locked=False,
-              add=False):
+              add=False,
+              overwrite=True):
         stage = Stage(project=project,
                       cwd=cwd,
                       cmd=cmd,
@@ -244,6 +246,12 @@ def loads(project=None,
         cwd = os.path.abspath(cwd)
         path = os.path.join(cwd, fname)
 
+        if os.path.exists(path):
+            relpath = os.path.relpath(path)
+            msg = "{} already exists. Do you wish to overwrite it?"
+            if not overwrite and not prompt(msg.format(relpath), False):
+                raise DvcException("{} already exists".format(relpath))
+
         stage.cwd = cwd
         stage.path = path
 


Test patch:
Repository: iterative/dvc

Issue:
help: format plain `dvc` output 
Currently `dvc` outputs:
```
$ dvc
usage: dvc [-h] [-q] [-v] [-V]
           {init,destroy,add,import,checkout,run,pull,push,fetch,status,repro,remove,move,gc,config,remote,met
rics,install,root,lock,unlock,pipeline}
```

Need to reformat.


Discussion:

Resolving patch:
diff --git a/dvc/cli.py b/dvc/cli.py
--- a/dvc/cli.py
+++ b/dvc/cli.py
@@ -71,8 +71,11 @@ def parse_args(argv=None):
 
     # Sub commands
     subparsers = parser.add_subparsers(
+                        title='Available Commands',
+                        metavar='COMMAND',
                         dest='cmd',
-                        help='Use dvc CMD --help for command-specific help')
+                        help='Use dvc COMMAND --help for command-specific '
+                             'help')
 
     _fix_subparsers(subparsers)
 


Test patch:
Repository: iterative/dvc

Issue:
calling `dvc` should print full help same as with `dvc -h`



Discussion:

Resolving patch:
diff --git a/dvc/cli.py b/dvc/cli.py
--- a/dvc/cli.py
+++ b/dvc/cli.py
@@ -39,6 +39,13 @@ def _fix_subparsers(subparsers):
         subparsers.dest = 'cmd'
 
 
+class DvcParser(argparse.ArgumentParser):
+    def error(self, message):
+        sys.stderr.write('error: %s\n' % message)
+        self.print_help()
+        sys.exit(2)
+
+
 class VersionAction(argparse.Action):
     def __call__(self, parser, namespace, values, option_string=None):
         print(VERSION)
@@ -63,11 +70,10 @@ def parse_args(argv=None):
 
     # Main parser
     desc = 'Data Version Control'
-    parser = argparse.ArgumentParser(
-                        prog='dvc',
-                        description=desc,
-                        parents=[parent_parser],
-                        formatter_class=argparse.RawTextHelpFormatter)
+    parser = DvcParser(prog='dvc',
+                       description=desc,
+                       parents=[parent_parser],
+                       formatter_class=argparse.RawTextHelpFormatter)
 
     # NOTE: On some python versions action='version' prints to stderr
     # instead of stdout https://bugs.python.org/issue18920


Test patch:
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
```


Discussion:
Hi @sotte !

Sorry, I accidentally pushed wrong version to pip. I released 0.15.3 already. Please upgrade.

Thank you,
Ruslan
That was quick. Thanks for the fix.
@sotte And thank you for the feedback! We really appreciate it! :slightly_smiling_face: 
I'm facing this problem again.
OS: Ubuntu (Mate) 16.04
Python: 3.6.6 (Anaconda)

```shell
$ pip install dvc
Collecting dvc
  Using cached 
.... (Some downloads)
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)
```

```shell
$ pip search dvc
dvc (0.16.3)  - Git for data scientists - manage your code and data together
```

@Hong-Xiang Thank you for reporting the issue! I'm already looking into it.

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -23,11 +23,9 @@
     "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",


Test patch:
Repository: iterative/dvc

Issue:
config: add ability to specify `--interactive` behaviour for `dvc run` as default
#894 

Kudos @prihoda for suggesting.


Discussion:

Resolving patch:
diff --git a/dvc/config.py b/dvc/config.py
--- a/dvc/config.py
+++ b/dvc/config.py
@@ -36,6 +36,14 @@ def supported_cloud(cloud):
     return cloud in ['aws', 'gcp', 'local', '']
 
 
+def is_bool(val):
+    return val.lower() in ['true', 'false']
+
+
+def to_bool(val):
+    return val.lower() == 'true'
+
+
 class Config(object):
     CONFIG = 'config'
     CONFIG_LOCAL = 'config.local'
@@ -44,6 +52,8 @@ class Config(object):
     SECTION_CORE_LOGLEVEL = 'loglevel'
     SECTION_CORE_LOGLEVEL_SCHEMA = And(Use(str.lower), supported_loglevel)
     SECTION_CORE_REMOTE = 'remote'
+    SECTION_CORE_INTERACTIVE_SCHEMA = And(str, is_bool, Use(to_bool))
+    SECTION_CORE_INTERACTIVE = 'interactive'
 
     SECTION_CACHE = 'cache'
     SECTION_CACHE_DIR = 'dir'
@@ -78,6 +88,8 @@ class Config(object):
                  default='info'): And(str, Use(str.lower),
                                       SECTION_CORE_LOGLEVEL_SCHEMA),
         Optional(SECTION_CORE_REMOTE, default=''): And(str, Use(str.lower)),
+        Optional(SECTION_CORE_INTERACTIVE,
+                 default=False): SECTION_CORE_INTERACTIVE_SCHEMA,
 
         # backward compatibility
         Optional(SECTION_CORE_CLOUD, default=''): SECTION_CORE_CLOUD_SCHEMA,
diff --git a/dvc/project.py b/dvc/project.py
--- a/dvc/project.py
+++ b/dvc/project.py
@@ -266,6 +266,11 @@ def reproduce(self,
         if node not in stages:
             raise NotDvcFileError(target)
 
+        if not interactive:
+            config = self.config
+            core = config._config[config.SECTION_CORE]
+            interactive = core.get(config.SECTION_CORE_INTERACTIVE, False)
+
         if recursive:
             return self._reproduce_stages(G,
                                           stages,


Test patch:
Repository: iterative/dvc

Issue:
`dvc status` print something even if project is just initialized
Empty outputs look like a bug


Discussion:

Resolving patch:
diff --git a/dvc/command/status.py b/dvc/command/status.py
--- a/dvc/command/status.py
+++ b/dvc/command/status.py
@@ -29,7 +29,11 @@ def do_run(self, target=None):
                                      cloud=self.args.cloud,
                                      show_checksums=self.args.show_checksums,
                                      remote=self.args.remote)
-            self._show(st, indent)
+            if st:
+                self._show(st, indent)
+            else:
+                self.project.logger.info("Nothing to reproduce. "
+                                         "Pipeline is up to date.")
         except Exception as exc:
             self.project.logger.error('Failed to obtain data status', exc)
             return 1


Test patch:
Repository: iterative/dvc

Issue:
`dvc destroy` does it remove data files as well?
Specify in the confirmation if that's the case. Fix docs. It feels a little bit dangerous. 


Discussion:

Resolving patch:
diff --git a/dvc/cli.py b/dvc/cli.py
--- a/dvc/cli.py
+++ b/dvc/cli.py
@@ -116,7 +116,8 @@ def parse_args(argv=None):
     init_parser.set_defaults(func=CmdInit)
 
     # Destroy
-    DESTROY_HELP = 'Destroy dvc.'
+    DESTROY_HELP = "Destroy dvc. Will remove all project's information, " \
+                   "data files and cache."
     destroy_parser = subparsers.add_parser(
                         'destroy',
                         parents=[parent_parser],
diff --git a/dvc/command/destroy.py b/dvc/command/destroy.py
--- a/dvc/command/destroy.py
+++ b/dvc/command/destroy.py
@@ -6,8 +6,8 @@
 class CmdDestroy(CmdBase):
     def run_cmd(self):
         try:
-            msg = u'This will destroy all information about your pipelines ' \
-                  u'as well as cache in .dvc/cache.\n' \
+            msg = u'This will destroy all information about your pipelines, ' \
+                  u'all data files, as well as cache in .dvc/cache.\n' \
                   u'Are you sure you want to continue?'
 
             if not self.args.force and not prompt(msg, False):


Test patch:
Repository: iterative/dvc

Issue:
logger: use colored prefix instead of coloring everything
I.e.

<img width="471" alt="screen shot 2018-08-21 at 7 06 27 pm" src="https://user-images.githubusercontent.com/5367102/44438936-1e972980-a5ca-11e8-8e04-9871fceb2b36.png">

Kudos @shcheklein 


Discussion:

Resolving patch:
diff --git a/dvc/logger.py b/dvc/logger.py
--- a/dvc/logger.py
+++ b/dvc/logger.py
@@ -84,20 +84,23 @@ def parse_exc(exc, tb=None):
 
     @staticmethod
     def error(msg, exc=None):
+        prefix = Logger.colorize('Error: ', 'error')
         str_exc, str_tb = Logger.parse_exc(exc)
         if Logger.logger().getEffectiveLevel() == logging.DEBUG and exc:
             str_tb = str_tb if str_tb else traceback.format_exc()
-            Logger.logger().error(str_tb)
-        return Logger.logger().error(Logger.colorize(msg + str_exc, 'error'))
+            Logger.logger().error(prefix + str_tb)
+        return Logger.logger().error(prefix + msg + str_exc)
 
     @staticmethod
     def warn(msg):
-        return Logger.logger().warn(Logger.colorize(msg, 'warn'))
+        prefix = Logger.colorize('Warning: ', 'warn')
+        return Logger.logger().warn(prefix + msg)
 
     @staticmethod
     def debug(msg):
-        return Logger.logger().debug(Logger.colorize(msg, 'debug'))
+        prefix = Logger.colorize('Debug: ', 'debug')
+        return Logger.logger().debug(prefix + msg)
 
     @staticmethod
     def info(msg):
-        return Logger.logger().info(Logger.colorize(msg, 'info'))
+        return Logger.logger().info(msg)


Test patch:
Repository: iterative/dvc

Issue:
argparse: Use the same colored prefix as in Logger
I.e. 

```
(dvc-dev) [ivan@ivan ~/Projects/myrepo]$ dvc repro
error: default target './Dvcfile' does not exist.
```

Kudos @shcheklein 


Discussion:

Resolving patch:
diff --git a/dvc/cli.py b/dvc/cli.py
--- a/dvc/cli.py
+++ b/dvc/cli.py
@@ -26,6 +26,7 @@
 from dvc.command.root import CmdRoot
 from dvc.command.lock import CmdLock, CmdUnlock
 from dvc.command.pipeline import CmdPipelineShow
+from dvc.logger import Logger
 from dvc import VERSION
 
 
@@ -41,7 +42,7 @@ def _fix_subparsers(subparsers):
 
 class DvcParser(argparse.ArgumentParser):
     def error(self, message):
-        sys.stderr.write('error: %s\n' % message)
+        sys.stderr.write('{}{}\n'.format(Logger.error_prefix(), message))
         self.print_help()
         sys.exit(2)
 
@@ -784,11 +785,7 @@ def parse_args(argv=None):
             cwd = os.curdir
         path = os.path.join(cwd, 'Dvcfile')
         if not os.path.exists(path):
-            msg = "error: default target '{}' does not exist.\n"
-            sys.stderr.write(msg.format(path))
-            sys.stderr.flush()
-            repro_parser.print_help()
-            sys.exit(2)
+            parser.error("default target '{}' does not exist.".format(path))
         args.targets = ['Dvcfile']
 
     return args
diff --git a/dvc/logger.py b/dvc/logger.py
--- a/dvc/logger.py
+++ b/dvc/logger.py
@@ -82,9 +82,25 @@ def parse_exc(exc, tb=None):
 
         return (str_exc, str_tb)
 
+    @staticmethod
+    def _prefix(msg, typ):
+        return Logger.colorize('{}: '.format(msg), typ)
+
+    @staticmethod
+    def error_prefix():
+        return Logger._prefix('Error', 'error')
+
+    @staticmethod
+    def warning_prefix():
+        return Logger._prefix('Warning', 'warn')
+
+    @staticmethod
+    def debug_prefix():
+        return Logger._prefix('Debug', 'debug')
+
     @staticmethod
     def error(msg, exc=None):
-        prefix = Logger.colorize('Error: ', 'error')
+        prefix = Logger.error_prefix()
         str_exc, str_tb = Logger.parse_exc(exc)
         if Logger.logger().getEffectiveLevel() == logging.DEBUG and exc:
             str_tb = str_tb if str_tb else traceback.format_exc()
@@ -93,13 +109,11 @@ def error(msg, exc=None):
 
     @staticmethod
     def warn(msg):
-        prefix = Logger.colorize('Warning: ', 'warn')
-        return Logger.logger().warn(prefix + msg)
+        return Logger.logger().warn(Logger.warning_prefix() + msg)
 
     @staticmethod
     def debug(msg):
-        prefix = Logger.colorize('Debug: ', 'debug')
-        return Logger.logger().debug(prefix + msg)
+        return Logger.logger().debug(Logger.debug_prefix() + msg)
 
     @staticmethod
     def info(msg):


Test patch:
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.
```




Discussion:

Resolving patch:
diff --git a/dvc/cli.py b/dvc/cli.py
--- 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


Test patch:
Repository: iterative/dvc

Issue:
dvc status error with S3 output
DVC version 0.17.1, installed with pip.

Running `dvc status` shows
```
Failed to obtain data status: 'OutputS3' object has no attribute 'rel_path'
```
and nothing else (e.g. files that are not output to S3)

My .dvc/config:
```
['remote "data"']
url = s3://xxxxx/data
[core]
remote = data
['remote "s3cache"']
url = s3://xxxxx/cache
[cache]
s3 = s3cache
```


Discussion:
Hi @chwonghk01 !

Could you please run `dvc status --verbose` once again and show us the output?

Btw, 0.18.2 is the latest version. Please consider upgrading(`pip install --upgrade dvc`).

Thanks,
Ruslan
@efiop I have updated the dvc and got the same error message.
```
$ dvc --version
0.18.2
$ dvc status --verbose
Error: Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/dvc/command/status.py", line 31, in do_run
    remote=self.args.remote)
  File "/usr/local/lib/python3.6/site-packages/dvc/project.py", line 496, in status
    return self._local_status(target)
  File "/usr/local/lib/python3.6/site-packages/dvc/project.py", line 457, in _local_status
    status.update(stage.status())
  File "/usr/local/lib/python3.6/site-packages/dvc/stage.py", line 399, in status
    ret.update(self._status(self.outs, 'outs'))
  File "/usr/local/lib/python3.6/site-packages/dvc/stage.py", line 386, in _status
    ret.update(entry.status())
  File "/usr/local/lib/python3.6/site-packages/dvc/dependency/base.py", line 62, in status
    return {self.rel_path: 'changed'}
AttributeError: 'OutputS3' object has no attribute 'rel_path'

Error: Failed to obtain data status: 'OutputS3' object has no attribute 'rel_path'
Thank you! Already preparing a patch. Will release 0.18.3 in an hour or so with the fix.

Resolving patch:
diff --git a/dvc/config.py b/dvc/config.py
--- a/dvc/config.py
+++ b/dvc/config.py
@@ -10,8 +10,9 @@
 
 class ConfigError(DvcException):
     """ DVC config exception """
-    def __init__(self, ex=None):
-        super(ConfigError, self).__init__('Config file error', ex)
+    def __init__(self, msg, ex=None):
+        super(ConfigError, self).__init__('Config file error: {}'.format(msg),
+                                          ex)
 
 
 def supported_url(url):
diff --git a/dvc/dependency/base.py b/dvc/dependency/base.py
--- a/dvc/dependency/base.py
+++ b/dvc/dependency/base.py
@@ -59,7 +59,11 @@ def changed(self):
     def status(self):
         if self.changed():
             # FIXME better msgs
-            return {self.rel_path: 'changed'}
+            if self.path_info['scheme'] == 'local':
+                p = self.rel_path
+            else:
+                p = self.path
+            return {p: 'changed'}
         return {}
 
     def save(self):


Test patch:
diff --git a/tests/test_repro.py b/tests/test_repro.py
--- a/tests/test_repro.py
+++ b/tests/test_repro.py
@@ -380,6 +380,8 @@ def test(self):
 
         sleep()
 
+        self.dvc.status()
+
         stages = self.dvc.reproduce(import_stage.path)
         self.assertEqual(len(stages), 1)
         self.assertTrue(os.path.exists('import'))
Repository: iterative/dvc

Issue:
repro: print msg when there is nothing to reproduve
https://discuss.dvc.org/t/tutorial-improvement-other-suggestions/79


Discussion:

Resolving patch:
diff --git a/dvc/command/repro.py b/dvc/command/repro.py
--- a/dvc/command/repro.py
+++ b/dvc/command/repro.py
@@ -1,6 +1,7 @@
 import os
 
 from dvc.command.base import CmdBase
+from dvc.command.status import CmdDataStatus
 from dvc.exceptions import DvcException
 
 
@@ -14,11 +15,16 @@ def run(self):
         ret = 0
         for target in self.args.targets:
             try:
-                self.project.reproduce(target,
+                stages = self.project.reproduce(
+                                       target,
                                        recursive=recursive,
                                        force=self.args.force,
                                        dry=self.args.dry,
                                        interactive=self.args.interactive)
+
+                if len(stages) == 0:
+                    self.project.logger.info(CmdDataStatus.UP_TO_DATE_MSG)
+
                 if self.args.metrics:
                     self.project.metrics_show()
             except DvcException as ex:
diff --git a/dvc/command/status.py b/dvc/command/status.py
--- a/dvc/command/status.py
+++ b/dvc/command/status.py
@@ -4,6 +4,7 @@
 class CmdDataStatus(CmdDataBase):
     STATUS_LEN = 10
     STATUS_INDENT = '\t'
+    UP_TO_DATE_MSG = "Pipeline is up to date. Nothing to reproduce."
 
     def _normalize(self, s):
         s += ':'
@@ -32,8 +33,8 @@ def do_run(self, target=None):
             if st:
                 self._show(st, indent)
             else:
-                self.project.logger.info("Nothing to reproduce. "
-                                         "Pipeline is up to date.")
+                self.project.logger.info(self.UP_TO_DATE_MSG)
+
         except Exception as exc:
             self.project.logger.error('Failed to obtain data status', exc)
             return 1


Test patch: