D4477: merge: move purge logic from extension
indygreg (Gregory Szorc)
phabricator at mercurial-scm.org
Fri Sep 7 12:12:59 UTC 2018
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG7fea205fd5dc: merge: move purge logic from extension (authored by indygreg, committed by ).
CHANGED PRIOR TO COMMIT
https://phab.mercurial-scm.org/D4477?vs=10825&id=10827#toc
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D4477?vs=10825&id=10827
REVISION DETAIL
https://phab.mercurial-scm.org/D4477
AFFECTED FILES
hgext/purge.py
mercurial/merge.py
CHANGE DETAILS
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -9,6 +9,7 @@
import errno
import hashlib
+import os
import shutil
import struct
@@ -2240,3 +2241,71 @@
# fix up dirstate for copies and renames
copies.duplicatecopies(repo, repo[None], ctx.rev(), pctx.rev())
return stats
+
+def purge(repo, matcher, ignored=False, removeemptydirs=True,
+ removefiles=True, abortonerror=False, noop=False):
+ """Purge the working directory of untracked files.
+
+ ``matcher`` is a matcher configured to scan the working directory -
+ potentially a subset.
+
+ ``ignored`` controls whether ignored files should also be purged.
+
+ ``removeemptydirs`` controls whether empty directories should be removed.
+
+ ``removefiles`` controls whether files are removed.
+
+ ``abortonerror`` causes an exception to be raised if an error occurs
+ deleting a file or directory.
+
+ ``noop`` controls whether to actually remove files. If not defined, actions
+ will be taken.
+
+ Returns an iterable of relative paths in the working directory that were
+ or would be removed.
+ """
+
+ def remove(removefn, path):
+ try:
+ removefn(repo.wvfs.join(path))
+ except OSError:
+ m = _('%s cannot be removed') % path
+ if abortonerror:
+ raise error.Abort(m)
+ else:
+ repo.ui.warn(_('warning: %s\n') % m)
+
+ # There's no API to copy a matcher. So mutate the passed matcher and
+ # restore it when we're done.
+ oldexplicitdir = matcher.explicitdir
+ oldtraversedir = matcher.traversedir
+
+ res = []
+
+ try:
+ if removeemptydirs:
+ directories = []
+ matcher.explicitdir = matcher.traversedir = directories.append
+
+ status = repo.status(match=matcher, ignored=ignored, unknown=True)
+
+ if removefiles:
+ for f in sorted(status.unknown + status.ignored):
+ if not noop:
+ repo.ui.note(_('removing file %s\n') % f)
+ remove(util.unlink, f)
+ res.append(f)
+
+ if removeemptydirs:
+ for f in sorted(directories, reverse=True):
+ if matcher(f) and not os.listdir(repo.wvfs.join(f)):
+ if not noop:
+ repo.ui.note(_('removing directory %s\n') % f)
+ remove(os.rmdir, f)
+ res.append(f)
+
+ return res
+
+ finally:
+ matcher.explicitdir = oldexplicitdir
+ matcher.traversedir = oldtraversedir
diff --git a/hgext/purge.py b/hgext/purge.py
--- a/hgext/purge.py
+++ b/hgext/purge.py
@@ -25,16 +25,13 @@
'''command to delete untracked files from the working directory'''
from __future__ import absolute_import
-import os
-
from mercurial.i18n import _
from mercurial import (
cmdutil,
- error,
+ merge as mergemod,
pycompat,
registrar,
scmutil,
- util,
)
cmdtable = {}
@@ -86,44 +83,28 @@
option.
'''
opts = pycompat.byteskwargs(opts)
+
act = not opts.get('print')
eol = '\n'
if opts.get('print0'):
eol = '\0'
act = False # --print0 implies --print
+
removefiles = opts.get('files')
removedirs = opts.get('dirs')
+
if not removefiles and not removedirs:
removefiles = True
removedirs = True
- def remove(remove_func, name):
- if act:
- try:
- remove_func(repo.wjoin(name))
- except OSError:
- m = _('%s cannot be removed') % name
- if opts.get('abort_on_err'):
- raise error.Abort(m)
- ui.warn(_('warning: %s\n') % m)
- else:
- ui.write('%s%s' % (name, eol))
+ match = scmutil.match(repo[None], dirs, opts)
- match = scmutil.match(repo[None], dirs, opts)
- if removedirs:
- directories = []
- match.explicitdir = match.traversedir = directories.append
- status = repo.status(match=match, ignored=opts.get('all'), unknown=True)
+ paths = mergemod.purge(
+ repo, match, ignored=opts.get('all', False),
+ removeemptydirs=removedirs, removefiles=removefiles,
+ abortonerror=opts.get('abort_on_err'),
+ noop=not act)
- if removefiles:
- for f in sorted(status.unknown + status.ignored):
- if act:
- ui.note(_('removing file %s\n') % f)
- remove(util.unlink, f)
-
- if removedirs:
- for f in sorted(directories, reverse=True):
- if match(f) and not os.listdir(repo.wjoin(f)):
- if act:
- ui.note(_('removing directory %s\n') % f)
- remove(os.rmdir, f)
+ for path in paths:
+ if not act:
+ ui.write('%s%s' % (path, eol))
To: indygreg, #hg-reviewers
Cc: yuja, mercurial-devel
More information about the Mercurial-devel
mailing list