We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
dvc repro --force does not work
It looks like the flag was just ignored.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `dvc/project.py`
Content:
```
1 import os
2 import stat
3 import networkx as nx
4 
5 import dvc.cloud.base as cloud
6 
7 from dvc.logger import Logger
8 from dvc.exceptions import DvcException
9 from dvc.stage import Stage, Output
10 from dvc.config import Config
11 from dvc.state import State
12 from dvc.lock import Lock
13 from dvc.scm import SCM
14 from dvc.cache import Cache
15 from dvc.cloud.data_cloud import DataCloud
16 from dvc.system import System
17 
18 
19 class StageNotFoundError(DvcException):
20     def __init__(self, path):
21         msg = 'Stage file {} does not exist'.format(path)
22         super(StageNotFoundError, self).__init__(msg)
23 
24 
25 class ReproductionError(DvcException):
26     def __init__(self, dvc_file_name, ex):
27         msg = 'Failed to reproduce \'{}\''.format(dvc_file_name)
28         super(ReproductionError, self).__init__(msg, cause=ex)
29 
30 
31 class Project(object):
32     DVC_DIR = '.dvc'
33 
34     def __init__(self, root_dir):
35         self.root_dir = os.path.abspath(os.path.realpath(root_dir))
36         self.dvc_dir = os.path.join(self.root_dir, self.DVC_DIR)
37 
38         self.scm = SCM(self.root_dir)
39         self.lock = Lock(self.dvc_dir)
40         self.cache = Cache(self.dvc_dir)
41         self.state = State(self.root_dir, self.dvc_dir)
42         self.config = Config(self.dvc_dir)
43         self.logger = Logger(self.config._config)
44         self.cloud = DataCloud(self.cache, self.config._config)
45 
46     @staticmethod
47     def init(root_dir=os.curdir):
48         """
49         Initiate dvc project in directory.
50 
51         Args:
52             root_dir: Path to project's root directory.
53 
54         Returns:
55             Project instance.
56 
57         Raises:
58             KeyError: Raises an exception.
59         """
60         root_dir = os.path.abspath(root_dir)
61         dvc_dir = os.path.join(root_dir, Project.DVC_DIR)
62         os.mkdir(dvc_dir)
63 
64         config = Config.init(dvc_dir)
65         cache = Cache.init(dvc_dir)
66         state = State.init(root_dir, dvc_dir)
67         lock = Lock(dvc_dir)
68 
69         scm = SCM(root_dir)
70         scm.ignore_list([cache.cache_dir,
71                          state.state_file,
72                          lock.lock_file])
73 
74         ignore_file = os.path.join(dvc_dir, scm.ignore_file())
75         scm.add([config.config_file, ignore_file])
76 
77         return Project(root_dir)
78 
79     def to_dvc_path(self, path):
80         return os.path.relpath(path, self.root_dir)
81 
82     def add(self, fname):
83         out = os.path.basename(fname)
84         stage_fname = out + Stage.STAGE_FILE_SUFFIX
85         cwd = os.path.dirname(os.path.abspath(fname))
86         stage = Stage.loads(project=self,
87                             cmd=None,
88                             deps=[],
89                             outs=[out],
90                             fname=stage_fname,
91                             cwd=cwd)
92 
93         stage.save()
94         stage.dump()
95         return stage
96 
97     def remove(self, target):
98         if not Stage.is_stage_file(target):
99             raise StageNotFoundError(target)
100 
101         stage = Stage.load(self, target)
102         for out in stage.outs:
103             out.remove()
104 
105         return stage
106 
107     def run(self,
108             cmd=None,
109             deps=[],
110             outs=[],
111             outs_no_cache=[],
112             fname=Stage.STAGE_FILE,
113             cwd=os.curdir,
114             no_exec=False):
115         stage = Stage.loads(project=self,
116                             fname=fname,
117                             cmd=cmd,
118                             cwd=cwd,
119                             outs=outs,
120                             outs_no_cache=outs_no_cache,
121                             deps=deps)
122         if not no_exec:
123             stage.run()
124         stage.dump()
125         return stage
126 
127     def _reproduce_stage(self, stages, node, force):
128         if not stages[node].changed():
129             return []
130 
131         stages[node].reproduce(force=force)
132         stages[node].dump()
133         return [stages[node]]
134 
135     def reproduce(self, target, recursive=True, force=False):
136         stages = nx.get_node_attributes(self.graph(), 'stage')
137         node = os.path.relpath(os.path.abspath(target), self.root_dir)
138         if node not in stages:
139             raise StageNotFoundError(target)
140 
141         if recursive:
142             return self._reproduce_stages(stages, node, force)
143 
144         return self._reproduce_stage(stages, node, force)
145 
146     def _reproduce_stages(self, stages, node, force):
147         result = []
148         for n in nx.dfs_postorder_nodes(self.graph(), node):
149             try:
150                 result += self._reproduce_stage(stages, n, force)
151             except Exception as ex:
152                 raise ReproductionError(stages[n].relpath, ex)
153         return result
154 
155     def _remove_untracked_hardlinks(self):
156         untracked = self.scm.untracked_files()
157         cache = dict((System.inode(c), c) for c in self.cache.all())
158         for file in untracked:
159             inode = System.inode(file)
160             if inode not in cache.keys():
161                 continue
162 
163             Logger.info(u'Remove \'{}\''.format(file))
164             os.remove(file)
165 
166             dir = os.path.dirname(file)
167             if len(dir) != 0 and not os.listdir(dir):
168                 Logger.info(u'Remove empty directory \'{}\''.format(dir))
169                 os.removedirs(dir)
170 
171     def checkout(self):
172         self._remove_untracked_hardlinks()
173         for stage in self.stages():
174             stage.checkout()
175 
176     def _used_cache(self, target=None):
177         cache_set = set()
178 
179         if target:
180             stages = [Stage.load(self, target)]
181         else:
182             stages = self.stages()
183 
184         for stage in stages:
185             for out in stage.outs:
186                 if not out.use_cache:
187                     continue
188                 cache_set |= set([out.cache])
189                 if out.is_dir_cache(out.cache) and os.path.isfile(out.cache):
190                     dir_cache = out.dir_cache()
191                     cache_set |= set(dir_cache.values())
192 
193         return list(cache_set)
194 
195     def gc(self):
196         clist = self._used_cache()
197         for cache in self.cache.all():
198             if cache in clist:
199                 continue
200             os.unlink(cache)
201             self.logger.info(u'\'{}\' was removed'.format(self.to_dvc_path(cache)))
202 
203     def push(self, target=None, jobs=1):
204         return self.cloud.push(self._used_cache(target), jobs)
205 
206     def fetch(self, target=None, jobs=1):
207         return self.cloud.pull(self._used_cache(target), jobs)
208 
209     def pull(self, target=None, jobs=1):
210         ret = self.fetch(target, jobs)
211         self.checkout()
212         return ret
213 
214     def _local_status(self, target=None):
215         status = {}
216 
217         if target:
218             stages = [Stage.load(self, target)]
219         else:
220             stages = self.stages()
221 
222         for stage in self.stages():
223             status.update(stage.status())
224 
225         return status
226 
227     def _cloud_status(self, target=None, jobs=1):
228         status = {}
229         for target, ret in self.cloud.status(self._used_cache(target), jobs):
230             if ret == cloud.STATUS_UNKNOWN or ret == cloud.STATUS_OK:
231                 continue
232 
233             prefix_map = {
234                 cloud.STATUS_DELETED: 'deleted',
235                 cloud.STATUS_MODIFIED: 'modified',
236                 cloud.STATUS_NEW: 'new',
237             }
238 
239             path = os.path.relpath(target, self.cache.cache_dir)
240 
241             status[path] = prefix_map[ret]
242 
243         return status
244 
245     def status(self, target=None, jobs=1, cloud=False):
246         if cloud:
247             return self._cloud_status(target, jobs)
248         return self._local_status(target)
249 
250     def graph(self):
251         G = nx.DiGraph()
252 
253         for stage in self.stages():
254             node = os.path.relpath(stage.path, self.root_dir)
255             G.add_node(node, stage=stage)
256             for dep in stage.deps:
257                 dep_stage = dep.stage()
258                 if not dep_stage:
259                     continue
260                 dep_node = os.path.relpath(dep_stage.path, self.root_dir)
261                 G.add_node(dep_node, stage=dep_stage)
262                 G.add_edge(node, dep_node)
263 
264         return G
265 
266     def stages(self):
267         stages = []
268         for root, dirs, files in os.walk(self.root_dir):
269             for fname in files:
270                 path = os.path.join(root, fname)
271                 if not Stage.is_stage_file(path):
272                     continue
273                 stages.append(Stage.load(self, path))
274         return stages
275 
276     def outs(self):
277         outs = []
278         for stage in self.stages():
279             outs += stage.outs
280         return outs
281
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/dvc/project.py b/dvc/project.py
--- a/dvc/project.py
+++ b/dvc/project.py
@@ -125,7 +125,7 @@
         return stage
 
     def _reproduce_stage(self, stages, node, force):
-        if not stages[node].changed():
+        if not stages[node].changed() and not force:
             return []
 
         stages[node].reproduce(force=force)

{"golden_diff": "diff --git a/dvc/project.py b/dvc/project.py\n--- a/dvc/project.py\n+++ b/dvc/project.py\n@@ -125,7 +125,7 @@\n         return stage\n \n     def _reproduce_stage(self, stages, node, force):\n-        if not stages[node].changed():\n+        if not stages[node].changed() and not force:\n             return []\n \n         stages[node].reproduce(force=force)\n", "issue": "dvc repro --force does not work\nIt looks like the flag was just ignored.\n", "before_files": [{"content": "import os\nimport stat\nimport networkx as nx\n\nimport dvc.cloud.base as cloud\n\nfrom dvc.logger import Logger\nfrom dvc.exceptions import DvcException\nfrom dvc.stage import Stage, Output\nfrom dvc.config import Config\nfrom dvc.state import State\nfrom dvc.lock import Lock\nfrom dvc.scm import SCM\nfrom dvc.cache import Cache\nfrom dvc.cloud.data_cloud import DataCloud\nfrom dvc.system import System\n\n\nclass StageNotFoundError(DvcException):\n    def __init__(self, path):\n        msg = 'Stage file {} does not exist'.format(path)\n        super(StageNotFoundError, self).__init__(msg)\n\n\nclass ReproductionError(DvcException):\n    def __init__(self, dvc_file_name, ex):\n        msg = 'Failed to reproduce \\'{}\\''.format(dvc_file_name)\n        super(ReproductionError, self).__init__(msg, cause=ex)\n\n\nclass Project(object):\n    DVC_DIR = '.dvc'\n\n    def __init__(self, root_dir):\n        self.root_dir = os.path.abspath(os.path.realpath(root_dir))\n        self.dvc_dir = os.path.join(self.root_dir, self.DVC_DIR)\n\n        self.scm = SCM(self.root_dir)\n        self.lock = Lock(self.dvc_dir)\n        self.cache = Cache(self.dvc_dir)\n        self.state = State(self.root_dir, self.dvc_dir)\n        self.config = Config(self.dvc_dir)\n        self.logger = Logger(self.config._config)\n        self.cloud = DataCloud(self.cache, self.config._config)\n\n    @staticmethod\n    def init(root_dir=os.curdir):\n        \"\"\"\n        Initiate dvc project in directory.\n\n        Args:\n            root_dir: Path to project's root directory.\n\n        Returns:\n            Project instance.\n\n        Raises:\n            KeyError: Raises an exception.\n        \"\"\"\n        root_dir = os.path.abspath(root_dir)\n        dvc_dir = os.path.join(root_dir, Project.DVC_DIR)\n        os.mkdir(dvc_dir)\n\n        config = Config.init(dvc_dir)\n        cache = Cache.init(dvc_dir)\n        state = State.init(root_dir, dvc_dir)\n        lock = Lock(dvc_dir)\n\n        scm = SCM(root_dir)\n        scm.ignore_list([cache.cache_dir,\n                         state.state_file,\n                         lock.lock_file])\n\n        ignore_file = os.path.join(dvc_dir, scm.ignore_file())\n        scm.add([config.config_file, ignore_file])\n\n        return Project(root_dir)\n\n    def to_dvc_path(self, path):\n        return os.path.relpath(path, self.root_dir)\n\n    def add(self, fname):\n        out = os.path.basename(fname)\n        stage_fname = out + Stage.STAGE_FILE_SUFFIX\n        cwd = os.path.dirname(os.path.abspath(fname))\n        stage = Stage.loads(project=self,\n                            cmd=None,\n                            deps=[],\n                            outs=[out],\n                            fname=stage_fname,\n                            cwd=cwd)\n\n        stage.save()\n        stage.dump()\n        return stage\n\n    def remove(self, target):\n        if not Stage.is_stage_file(target):\n            raise StageNotFoundError(target)\n\n        stage = Stage.load(self, target)\n        for out in stage.outs:\n            out.remove()\n\n        return stage\n\n    def run(self,\n            cmd=None,\n            deps=[],\n            outs=[],\n            outs_no_cache=[],\n            fname=Stage.STAGE_FILE,\n            cwd=os.curdir,\n            no_exec=False):\n        stage = Stage.loads(project=self,\n                            fname=fname,\n                            cmd=cmd,\n                            cwd=cwd,\n                            outs=outs,\n                            outs_no_cache=outs_no_cache,\n                            deps=deps)\n        if not no_exec:\n            stage.run()\n        stage.dump()\n        return stage\n\n    def _reproduce_stage(self, stages, node, force):\n        if not stages[node].changed():\n            return []\n\n        stages[node].reproduce(force=force)\n        stages[node].dump()\n        return [stages[node]]\n\n    def reproduce(self, target, recursive=True, force=False):\n        stages = nx.get_node_attributes(self.graph(), 'stage')\n        node = os.path.relpath(os.path.abspath(target), self.root_dir)\n        if node not in stages:\n            raise StageNotFoundError(target)\n\n        if recursive:\n            return self._reproduce_stages(stages, node, force)\n\n        return self._reproduce_stage(stages, node, force)\n\n    def _reproduce_stages(self, stages, node, force):\n        result = []\n        for n in nx.dfs_postorder_nodes(self.graph(), node):\n            try:\n                result += self._reproduce_stage(stages, n, force)\n            except Exception as ex:\n                raise ReproductionError(stages[n].relpath, ex)\n        return result\n\n    def _remove_untracked_hardlinks(self):\n        untracked = self.scm.untracked_files()\n        cache = dict((System.inode(c), c) for c in self.cache.all())\n        for file in untracked:\n            inode = System.inode(file)\n            if inode not in cache.keys():\n                continue\n\n            Logger.info(u'Remove \\'{}\\''.format(file))\n            os.remove(file)\n\n            dir = os.path.dirname(file)\n            if len(dir) != 0 and not os.listdir(dir):\n                Logger.info(u'Remove empty directory \\'{}\\''.format(dir))\n                os.removedirs(dir)\n\n    def checkout(self):\n        self._remove_untracked_hardlinks()\n        for stage in self.stages():\n            stage.checkout()\n\n    def _used_cache(self, target=None):\n        cache_set = set()\n\n        if target:\n            stages = [Stage.load(self, target)]\n        else:\n            stages = self.stages()\n\n        for stage in stages:\n            for out in stage.outs:\n                if not out.use_cache:\n                    continue\n                cache_set |= set([out.cache])\n                if out.is_dir_cache(out.cache) and os.path.isfile(out.cache):\n                    dir_cache = out.dir_cache()\n                    cache_set |= set(dir_cache.values())\n\n        return list(cache_set)\n\n    def gc(self):\n        clist = self._used_cache()\n        for cache in self.cache.all():\n            if cache in clist:\n                continue\n            os.unlink(cache)\n            self.logger.info(u'\\'{}\\' was removed'.format(self.to_dvc_path(cache)))\n\n    def push(self, target=None, jobs=1):\n        return self.cloud.push(self._used_cache(target), jobs)\n\n    def fetch(self, target=None, jobs=1):\n        return self.cloud.pull(self._used_cache(target), jobs)\n\n    def pull(self, target=None, jobs=1):\n        ret = self.fetch(target, jobs)\n        self.checkout()\n        return ret\n\n    def _local_status(self, target=None):\n        status = {}\n\n        if target:\n            stages = [Stage.load(self, target)]\n        else:\n            stages = self.stages()\n\n        for stage in self.stages():\n            status.update(stage.status())\n\n        return status\n\n    def _cloud_status(self, target=None, jobs=1):\n        status = {}\n        for target, ret in self.cloud.status(self._used_cache(target), jobs):\n            if ret == cloud.STATUS_UNKNOWN or ret == cloud.STATUS_OK:\n                continue\n\n            prefix_map = {\n                cloud.STATUS_DELETED: 'deleted',\n                cloud.STATUS_MODIFIED: 'modified',\n                cloud.STATUS_NEW: 'new',\n            }\n\n            path = os.path.relpath(target, self.cache.cache_dir)\n\n            status[path] = prefix_map[ret]\n\n        return status\n\n    def status(self, target=None, jobs=1, cloud=False):\n        if cloud:\n            return self._cloud_status(target, jobs)\n        return self._local_status(target)\n\n    def graph(self):\n        G = nx.DiGraph()\n\n        for stage in self.stages():\n            node = os.path.relpath(stage.path, self.root_dir)\n            G.add_node(node, stage=stage)\n            for dep in stage.deps:\n                dep_stage = dep.stage()\n                if not dep_stage:\n                    continue\n                dep_node = os.path.relpath(dep_stage.path, self.root_dir)\n                G.add_node(dep_node, stage=dep_stage)\n                G.add_edge(node, dep_node)\n\n        return G\n\n    def stages(self):\n        stages = []\n        for root, dirs, files in os.walk(self.root_dir):\n            for fname in files:\n                path = os.path.join(root, fname)\n                if not Stage.is_stage_file(path):\n                    continue\n                stages.append(Stage.load(self, path))\n        return stages\n\n    def outs(self):\n        outs = []\n        for stage in self.stages():\n            outs += stage.outs\n        return outs\n", "path": "dvc/project.py"}], "after_files": [{"content": "import os\nimport stat\nimport networkx as nx\n\nimport dvc.cloud.base as cloud\n\nfrom dvc.logger import Logger\nfrom dvc.exceptions import DvcException\nfrom dvc.stage import Stage, Output\nfrom dvc.config import Config\nfrom dvc.state import State\nfrom dvc.lock import Lock\nfrom dvc.scm import SCM\nfrom dvc.cache import Cache\nfrom dvc.cloud.data_cloud import DataCloud\nfrom dvc.system import System\n\n\nclass StageNotFoundError(DvcException):\n    def __init__(self, path):\n        msg = 'Stage file {} does not exist'.format(path)\n        super(StageNotFoundError, self).__init__(msg)\n\n\nclass ReproductionError(DvcException):\n    def __init__(self, dvc_file_name, ex):\n        msg = 'Failed to reproduce \\'{}\\''.format(dvc_file_name)\n        super(ReproductionError, self).__init__(msg, cause=ex)\n\n\nclass Project(object):\n    DVC_DIR = '.dvc'\n\n    def __init__(self, root_dir):\n        self.root_dir = os.path.abspath(os.path.realpath(root_dir))\n        self.dvc_dir = os.path.join(self.root_dir, self.DVC_DIR)\n\n        self.scm = SCM(self.root_dir)\n        self.lock = Lock(self.dvc_dir)\n        self.cache = Cache(self.dvc_dir)\n        self.state = State(self.root_dir, self.dvc_dir)\n        self.config = Config(self.dvc_dir)\n        self.logger = Logger(self.config._config)\n        self.cloud = DataCloud(self.cache, self.config._config)\n\n    @staticmethod\n    def init(root_dir=os.curdir):\n        \"\"\"\n        Initiate dvc project in directory.\n\n        Args:\n            root_dir: Path to project's root directory.\n\n        Returns:\n            Project instance.\n\n        Raises:\n            KeyError: Raises an exception.\n        \"\"\"\n        root_dir = os.path.abspath(root_dir)\n        dvc_dir = os.path.join(root_dir, Project.DVC_DIR)\n        os.mkdir(dvc_dir)\n\n        config = Config.init(dvc_dir)\n        cache = Cache.init(dvc_dir)\n        state = State.init(root_dir, dvc_dir)\n        lock = Lock(dvc_dir)\n\n        scm = SCM(root_dir)\n        scm.ignore_list([cache.cache_dir,\n                         state.state_file,\n                         lock.lock_file])\n\n        ignore_file = os.path.join(dvc_dir, scm.ignore_file())\n        scm.add([config.config_file, ignore_file])\n\n        return Project(root_dir)\n\n    def to_dvc_path(self, path):\n        return os.path.relpath(path, self.root_dir)\n\n    def add(self, fname):\n        out = os.path.basename(fname)\n        stage_fname = out + Stage.STAGE_FILE_SUFFIX\n        cwd = os.path.dirname(os.path.abspath(fname))\n        stage = Stage.loads(project=self,\n                            cmd=None,\n                            deps=[],\n                            outs=[out],\n                            fname=stage_fname,\n                            cwd=cwd)\n\n        stage.save()\n        stage.dump()\n        return stage\n\n    def remove(self, target):\n        if not Stage.is_stage_file(target):\n            raise StageNotFoundError(target)\n\n        stage = Stage.load(self, target)\n        for out in stage.outs:\n            out.remove()\n\n        return stage\n\n    def run(self,\n            cmd=None,\n            deps=[],\n            outs=[],\n            outs_no_cache=[],\n            fname=Stage.STAGE_FILE,\n            cwd=os.curdir,\n            no_exec=False):\n        stage = Stage.loads(project=self,\n                            fname=fname,\n                            cmd=cmd,\n                            cwd=cwd,\n                            outs=outs,\n                            outs_no_cache=outs_no_cache,\n                            deps=deps)\n        if not no_exec:\n            stage.run()\n        stage.dump()\n        return stage\n\n    def _reproduce_stage(self, stages, node, force):\n        if not stages[node].changed() and not force:\n            return []\n\n        stages[node].reproduce(force=force)\n        stages[node].dump()\n        return [stages[node]]\n\n    def reproduce(self, target, recursive=True, force=False):\n        stages = nx.get_node_attributes(self.graph(), 'stage')\n        node = os.path.relpath(os.path.abspath(target), self.root_dir)\n        if node not in stages:\n            raise StageNotFoundError(target)\n\n        if recursive:\n            return self._reproduce_stages(stages, node, force)\n\n        return self._reproduce_stage(stages, node, force)\n\n    def _reproduce_stages(self, stages, node, force):\n        result = []\n        for n in nx.dfs_postorder_nodes(self.graph(), node):\n            try:\n                result += self._reproduce_stage(stages, n, force)\n            except Exception as ex:\n                raise ReproductionError(stages[n].relpath, ex)\n        return result\n\n    def _remove_untracked_hardlinks(self):\n        untracked = self.scm.untracked_files()\n        cache = dict((System.inode(c), c) for c in self.cache.all())\n        for file in untracked:\n            inode = System.inode(file)\n            if inode not in cache.keys():\n                continue\n\n            Logger.info(u'Remove \\'{}\\''.format(file))\n            os.remove(file)\n\n            dir = os.path.dirname(file)\n            if len(dir) != 0 and not os.listdir(dir):\n                Logger.info(u'Remove empty directory \\'{}\\''.format(dir))\n                os.removedirs(dir)\n\n    def checkout(self):\n        self._remove_untracked_hardlinks()\n        for stage in self.stages():\n            stage.checkout()\n\n    def _used_cache(self, target=None):\n        cache_set = set()\n\n        if target:\n            stages = [Stage.load(self, target)]\n        else:\n            stages = self.stages()\n\n        for stage in stages:\n            for out in stage.outs:\n                if not out.use_cache:\n                    continue\n                cache_set |= set([out.cache])\n                if out.is_dir_cache(out.cache) and os.path.isfile(out.cache):\n                    dir_cache = out.dir_cache()\n                    cache_set |= set(dir_cache.values())\n\n        return list(cache_set)\n\n    def gc(self):\n        clist = self._used_cache()\n        for cache in self.cache.all():\n            if cache in clist:\n                continue\n            os.unlink(cache)\n            self.logger.info(u'\\'{}\\' was removed'.format(self.to_dvc_path(cache)))\n\n    def push(self, target=None, jobs=1):\n        return self.cloud.push(self._used_cache(target), jobs)\n\n    def fetch(self, target=None, jobs=1):\n        return self.cloud.pull(self._used_cache(target), jobs)\n\n    def pull(self, target=None, jobs=1):\n        ret = self.fetch(target, jobs)\n        self.checkout()\n        return ret\n\n    def _local_status(self, target=None):\n        status = {}\n\n        if target:\n            stages = [Stage.load(self, target)]\n        else:\n            stages = self.stages()\n\n        for stage in self.stages():\n            status.update(stage.status())\n\n        return status\n\n    def _cloud_status(self, target=None, jobs=1):\n        status = {}\n        for target, ret in self.cloud.status(self._used_cache(target), jobs):\n            if ret == cloud.STATUS_UNKNOWN or ret == cloud.STATUS_OK:\n                continue\n\n            prefix_map = {\n                cloud.STATUS_DELETED: 'deleted',\n                cloud.STATUS_MODIFIED: 'modified',\n                cloud.STATUS_NEW: 'new',\n            }\n\n            path = os.path.relpath(target, self.cache.cache_dir)\n\n            status[path] = prefix_map[ret]\n\n        return status\n\n    def status(self, target=None, jobs=1, cloud=False):\n        if cloud:\n            return self._cloud_status(target, jobs)\n        return self._local_status(target)\n\n    def graph(self):\n        G = nx.DiGraph()\n\n        for stage in self.stages():\n            node = os.path.relpath(stage.path, self.root_dir)\n            G.add_node(node, stage=stage)\n            for dep in stage.deps:\n                dep_stage = dep.stage()\n                if not dep_stage:\n                    continue\n                dep_node = os.path.relpath(dep_stage.path, self.root_dir)\n                G.add_node(dep_node, stage=dep_stage)\n                G.add_edge(node, dep_node)\n\n        return G\n\n    def stages(self):\n        stages = []\n        for root, dirs, files in os.walk(self.root_dir):\n            for fname in files:\n                path = os.path.join(root, fname)\n                if not Stage.is_stage_file(path):\n                    continue\n                stages.append(Stage.load(self, path))\n        return stages\n\n    def outs(self):\n        outs = []\n        for stage in self.stages():\n            outs += stage.outs\n        return outs\n", "path": "dvc/project.py"}]}