diff --git a/dvc/cli.py b/dvc/cli.py index a5344e07b..320d7a422 100644 --- a/dvc/cli.py +++ b/dvc/cli.py @@ -245,9 +245,6 @@ def parse_args(argv=None): 'gc', parents=[parent_parser], help='Collect garbage') - gc_parser.add_argument('target', - nargs='*', - help='Target to remove - file or directory.') gc_parser.add_argument('-l', '--keep-in-cloud', action='store_true', diff --git a/dvc/command/gc.py b/dvc/command/gc.py index c303fadaf..88142e264 100644 --- a/dvc/command/gc.py +++ b/dvc/command/gc.py @@ -1,41 +1,45 @@ import os +from dvc.command.base import DvcLock from dvc.command.traverse import Traverse from dvc.logger import Logger - +from dvc.path.data_item import DataItemError class CmdGC(Traverse): def __init__(self, settings): super(CmdGC, self).__init__(settings, "garbage collect", do_not_start_from_root=False) + self.clist = [] + + def run(self): + with DvcLock(self.is_locker, self.git): + if not self._traverse(self.git.git_dir_abs): + Logger.error('Failed to collect used cache') + return 1 + + for cache in os.listdir(self.settings.config.cache_dir): + fname = os.path.join(self.settings.config.cache_dir, cache) + if fname in self.clist: + continue + os.remove(fname) + self._remove_cloud_cache(self.settings.path_factory.data_item('.empty', fname)) + Logger.info('Cache \'{}\' was removed'.format(fname)) + + return 0 def process_file(self, target): Logger.debug(u'[Cmd-GC] GC file {}.'.format(target)) - data_item = self._get_data_item(target) - - for cache_data_item in data_item.get_all_caches(): - if cache_data_item.cache.relative != data_item.resolved_cache.relative: - os.remove(cache_data_item.cache.relative) - Logger.info(u'GC cache file {} was removed'.format(cache_data_item.cache.relative)) - self._remove_cloud_cache(cache_data_item) + try: + data_item = self.settings.path_factory.existing_data_item(target) + except DataItemError: + return + self.clist.append(data_item.cache.relative) Logger.debug(u'[Cmd-GC] GC data item {}. Success.'.format(data_item.data.relative)) - pass def is_recursive(self): return self.parsed_args.recursive - # Renaming - def gc_dir(self, target): - Logger.debug(u'[Cmd-GC] GC dir {}.'.format(target)) - return self._traverse_dir(target) - - def gc_file(self, target): - self.process_file(target) - - def gc_all(self): - return self._traverse_all() - @property def no_git_actions(self): return True diff --git a/dvc/command/traverse.py b/dvc/command/traverse.py index 2a29ab796..b4be15839 100644 --- a/dvc/command/traverse.py +++ b/dvc/command/traverse.py @@ -53,6 +53,9 @@ class Traverse(CmdBase): return False def _traverse_dir(self, target): + if target == self.settings.config.CONFIG_DIR: + return + for f in os.listdir(target): file = os.path.join(target, f) if os.path.isdir(file): diff --git a/dvc/path/data_item.py b/dvc/path/data_item.py index 1620868ed..de93fe5ff 100644 --- a/dvc/path/data_item.py +++ b/dvc/path/data_item.py @@ -91,19 +91,6 @@ class DataItem(object): cache_file = os.path.join(cache_dir, file_name) return Path(cache_file, self._git) - def get_all_caches(self): - result = [] - - suffix_len = self._git.COMMIT_LEN + len(self.CACHE_FILE_SEP) - cache_prefix = os.path.basename(self.resolved_cache.relative[:-suffix_len]) - - for cache_file in os.listdir(self.resolved_cache.dirname): - if cache_file[:-suffix_len] == cache_prefix: - data_item = self.copy(os.path.join(self.resolved_cache.dirname, cache_file)) - result.append(data_item) - - return result - @cached_property def resolved_cache(self): resolved_cache = os.path.realpath(self._data.relative)