5 # This software may be used and distributed according to the terms of the |
5 # This software may be used and distributed according to the terms of the |
6 # GNU General Public License version 2 or any later version. |
6 # GNU General Public License version 2 or any later version. |
7 |
7 |
8 from __future__ import absolute_import |
8 from __future__ import absolute_import |
9 |
9 |
|
10 import collections |
10 import hashlib |
11 import hashlib |
11 import os |
12 import os |
12 |
13 |
13 from .i18n import _ |
14 from .i18n import _ |
14 from .node import nullid |
15 from .node import nullid |
15 from . import ( |
16 from . import ( |
16 error, |
17 error, |
17 match as matchmod, |
18 match as matchmod, |
|
19 merge as mergemod, |
18 pycompat, |
20 pycompat, |
19 ) |
21 ) |
20 |
22 |
21 # Whether sparse features are enabled. This variable is intended to be |
23 # Whether sparse features are enabled. This variable is intended to be |
22 # temporary to facilitate porting sparse to core. It should eventually be |
24 # temporary to facilitate porting sparse to core. It should eventually be |
195 includes = readtemporaryincludes(repo) |
197 includes = readtemporaryincludes(repo) |
196 for i in additional: |
198 for i in additional: |
197 includes.add(i) |
199 includes.add(i) |
198 writetemporaryincludes(repo, includes) |
200 writetemporaryincludes(repo, includes) |
199 |
201 |
|
202 def prunetemporaryincludes(repo): |
|
203 if not enabled or not repo.vfs.exists('tempsparse'): |
|
204 return |
|
205 |
|
206 origstatus = repo.status() |
|
207 modified, added, removed, deleted, a, b, c = origstatus |
|
208 if modified or added or removed or deleted: |
|
209 # Still have pending changes. Don't bother trying to prune. |
|
210 return |
|
211 |
|
212 sparsematch = matcher(repo, includetemp=False) |
|
213 dirstate = repo.dirstate |
|
214 actions = [] |
|
215 dropped = [] |
|
216 tempincludes = readtemporaryincludes(repo) |
|
217 for file in tempincludes: |
|
218 if file in dirstate and not sparsematch(file): |
|
219 message = _('dropping temporarily included sparse files') |
|
220 actions.append((file, None, message)) |
|
221 dropped.append(file) |
|
222 |
|
223 typeactions = collections.defaultdict(list) |
|
224 typeactions['r'] = actions |
|
225 mergemod.applyupdates(repo, typeactions, repo[None], repo['.'], False) |
|
226 |
|
227 # Fix dirstate |
|
228 for file in dropped: |
|
229 dirstate.drop(file) |
|
230 |
|
231 repo.vfs.unlink('tempsparse') |
|
232 invalidatesignaturecache(repo) |
|
233 msg = _('cleaned up %d temporarily added file(s) from the ' |
|
234 'sparse checkout\n') |
|
235 repo.ui.status(msg % len(tempincludes)) |
|
236 |
200 def matcher(repo, revs=None, includetemp=True): |
237 def matcher(repo, revs=None, includetemp=True): |
201 """Obtain a matcher for sparse working directories for the given revs. |
238 """Obtain a matcher for sparse working directories for the given revs. |
202 |
239 |
203 If multiple revisions are specified, the matcher is the union of all |
240 If multiple revisions are specified, the matcher is the union of all |
204 revs. |
241 revs. |