--- a/hgext/purge.py Fri Jun 20 16:15:38 2014 +0900
+++ b/hgext/purge.py Thu Nov 07 17:24:14 2013 -0800
@@ -35,6 +35,8 @@
@command('purge|clean',
[('a', 'abort-on-err', None, _('abort if an error occurs')),
('', 'all', None, _('purge ignored files too')),
+ ('', 'dirs', None, _('purge empty directories')),
+ ('', 'files', None, _('purge files')),
('p', 'print', None, _('print filenames instead of deleting them')),
('0', 'print0', None, _('end filenames with NUL, for use with xargs'
' (implies -p/--print)')),
@@ -46,7 +48,7 @@
Delete files not known to Mercurial. This is useful to test local
and uncommitted changes in an otherwise-clean source tree.
- This means that purge will delete:
+ This means that purge will delete the following by default:
- Unknown files: files marked with "?" by :hg:`status`
- Empty directories: in fact Mercurial ignores directories unless
@@ -58,6 +60,10 @@
- Ignored files (unless --all is specified)
- New files added to the repository (with :hg:`add`)
+ The --files and --dirs options can be used to direct purge to delete
+ only files, only directories, or both. If neither option is given,
+ both will be deleted.
+
If directories are given on the command line, only files in these
directories are considered.
@@ -71,6 +77,11 @@
if opts['print0']:
eol = '\0'
act = False # --print0 implies --print
+ removefiles = opts['files']
+ removedirs = opts['dirs']
+ if not removefiles and not removedirs:
+ removefiles = True
+ removedirs = True
def remove(remove_func, name):
if act:
@@ -100,13 +111,15 @@
match.explicitdir = match.traversedir = directories.append
status = repo.status(match=match, ignored=opts['all'], unknown=True)
- for f in sorted(status[4] + status[5]):
- if act:
- ui.note(_('removing file %s\n') % f)
- remove(removefile, f)
+ if removefiles:
+ for f in sorted(status[4] + status[5]):
+ if act:
+ ui.note(_('removing file %s\n') % f)
+ remove(removefile, f)
- 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)
+ 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)
--- a/tests/test-purge.t Fri Jun 20 16:15:38 2014 +0900
+++ b/tests/test-purge.t Thu Nov 07 17:24:14 2013 -0800
@@ -215,4 +215,50 @@
$ hg purge -p -X .svn -X '*/.svn'
$ hg purge -p -X re:.*.svn
+ $ rm -R .svn directory r1
+
+only remove files
+
+ $ mkdir -p empty_dir dir
+ $ touch untracked_file dir/untracked_file
+ $ hg purge -p --files
+ dir/untracked_file
+ untracked_file
+ $ hg purge -v --files
+ removing file dir/untracked_file
+ removing file untracked_file
+ $ ls
+ dir
+ empty_dir
+ $ ls dir
+
+only remove dirs
+
+ $ mkdir -p empty_dir dir
+ $ touch untracked_file dir/untracked_file
+ $ hg purge -p --dirs
+ empty_dir
+ $ hg purge -v --dirs
+ removing directory empty_dir
+ $ ls
+ dir
+ untracked_file
+ $ ls dir
+ untracked_file
+
+remove both files and dirs
+
+ $ mkdir -p empty_dir dir
+ $ touch untracked_file dir/untracked_file
+ $ hg purge -p --files --dirs
+ dir/untracked_file
+ untracked_file
+ empty_dir
+ $ hg purge -v --files --dirs
+ removing file dir/untracked_file
+ removing file untracked_file
+ removing directory empty_dir
+ removing directory dir
+ $ ls
+
$ cd ..