Mercurial > hg
comparison mercurial/merge.py @ 39463:7fea205fd5dc
merge: move purge logic from extension
Working directory purging feels like functionality that should be
in core rather than in an extension.
This commit effectively moves the core purging logic from the
purge extension to merge.py.
Code was refactored slightly. Rather than deal with printing in
this function, the function is a generator of paths and the caller
can worry about printing.
Differential Revision: https://phab.mercurial-scm.org/D4477
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Thu, 06 Sep 2018 18:30:12 -0700 |
parents | d49e490a9e85 |
children | 3dd34b401bc2 |
comparison
equal
deleted
inserted
replaced
39462:e5449ff273d6 | 39463:7fea205fd5dc |
---|---|
7 | 7 |
8 from __future__ import absolute_import | 8 from __future__ import absolute_import |
9 | 9 |
10 import errno | 10 import errno |
11 import hashlib | 11 import hashlib |
12 import os | |
12 import shutil | 13 import shutil |
13 import struct | 14 import struct |
14 | 15 |
15 from .i18n import _ | 16 from .i18n import _ |
16 from .node import ( | 17 from .node import ( |
2238 repo.setparents(repo['.'].node(), pother) | 2239 repo.setparents(repo['.'].node(), pother) |
2239 repo.dirstate.write(repo.currenttransaction()) | 2240 repo.dirstate.write(repo.currenttransaction()) |
2240 # fix up dirstate for copies and renames | 2241 # fix up dirstate for copies and renames |
2241 copies.duplicatecopies(repo, repo[None], ctx.rev(), pctx.rev()) | 2242 copies.duplicatecopies(repo, repo[None], ctx.rev(), pctx.rev()) |
2242 return stats | 2243 return stats |
2244 | |
2245 def purge(repo, matcher, ignored=False, removeemptydirs=True, | |
2246 removefiles=True, abortonerror=False, noop=False): | |
2247 """Purge the working directory of untracked files. | |
2248 | |
2249 ``matcher`` is a matcher configured to scan the working directory - | |
2250 potentially a subset. | |
2251 | |
2252 ``ignored`` controls whether ignored files should also be purged. | |
2253 | |
2254 ``removeemptydirs`` controls whether empty directories should be removed. | |
2255 | |
2256 ``removefiles`` controls whether files are removed. | |
2257 | |
2258 ``abortonerror`` causes an exception to be raised if an error occurs | |
2259 deleting a file or directory. | |
2260 | |
2261 ``noop`` controls whether to actually remove files. If not defined, actions | |
2262 will be taken. | |
2263 | |
2264 Returns an iterable of relative paths in the working directory that were | |
2265 or would be removed. | |
2266 """ | |
2267 | |
2268 def remove(removefn, path): | |
2269 try: | |
2270 removefn(repo.wvfs.join(path)) | |
2271 except OSError: | |
2272 m = _('%s cannot be removed') % path | |
2273 if abortonerror: | |
2274 raise error.Abort(m) | |
2275 else: | |
2276 repo.ui.warn(_('warning: %s\n') % m) | |
2277 | |
2278 # There's no API to copy a matcher. So mutate the passed matcher and | |
2279 # restore it when we're done. | |
2280 oldexplicitdir = matcher.explicitdir | |
2281 oldtraversedir = matcher.traversedir | |
2282 | |
2283 res = [] | |
2284 | |
2285 try: | |
2286 if removeemptydirs: | |
2287 directories = [] | |
2288 matcher.explicitdir = matcher.traversedir = directories.append | |
2289 | |
2290 status = repo.status(match=matcher, ignored=ignored, unknown=True) | |
2291 | |
2292 if removefiles: | |
2293 for f in sorted(status.unknown + status.ignored): | |
2294 if not noop: | |
2295 repo.ui.note(_('removing file %s\n') % f) | |
2296 remove(util.unlink, f) | |
2297 res.append(f) | |
2298 | |
2299 if removeemptydirs: | |
2300 for f in sorted(directories, reverse=True): | |
2301 if matcher(f) and not os.listdir(repo.wvfs.join(f)): | |
2302 if not noop: | |
2303 repo.ui.note(_('removing directory %s\n') % f) | |
2304 remove(os.rmdir, f) | |
2305 res.append(f) | |
2306 | |
2307 return res | |
2308 | |
2309 finally: | |
2310 matcher.explicitdir = oldexplicitdir | |
2311 matcher.traversedir = oldtraversedir |