2006-05-12 22:26:19 +04:00
|
|
|
# Copyright (C) 2006 - Marco Barisione <marco@barisione.org>
|
|
|
|
#
|
2015-09-30 23:43:49 +03:00
|
|
|
# This is a small extension for Mercurial (https://mercurial-scm.org/)
|
2006-05-12 22:26:19 +04:00
|
|
|
# that removes files not known to mercurial
|
|
|
|
#
|
2009-07-26 03:59:28 +04:00
|
|
|
# This program was inspired by the "cvspurge" script contained in CVS
|
|
|
|
# utilities (http://www.red-bean.com/cvsutils/).
|
2007-02-27 11:05:36 +03:00
|
|
|
#
|
|
|
|
# For help on the usage of "hg purge" use:
|
|
|
|
# hg help purge
|
|
|
|
#
|
2006-05-12 22:26:19 +04:00
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
2012-01-06 19:27:13 +04:00
|
|
|
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
2006-05-12 22:26:19 +04:00
|
|
|
|
2009-06-24 15:42:02 +04:00
|
|
|
'''command to delete untracked files from the working directory'''
|
2016-03-03 00:39:55 +03:00
|
|
|
from __future__ import absolute_import
|
2009-06-21 18:45:47 +04:00
|
|
|
|
2014-08-05 00:24:57 +04:00
|
|
|
import os
|
2006-05-12 22:26:19 +04:00
|
|
|
|
2016-05-14 08:03:12 +03:00
|
|
|
from mercurial.i18n import _
|
2016-03-03 00:39:55 +03:00
|
|
|
from mercurial import (
|
|
|
|
commands,
|
|
|
|
error,
|
2016-01-09 17:07:20 +03:00
|
|
|
registrar,
|
2016-03-03 00:39:55 +03:00
|
|
|
scmutil,
|
|
|
|
util,
|
|
|
|
)
|
|
|
|
|
2011-05-12 22:14:42 +04:00
|
|
|
cmdtable = {}
|
2016-01-09 17:07:20 +03:00
|
|
|
command = registrar.command(cmdtable)
|
2016-08-23 18:26:08 +03:00
|
|
|
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
|
2015-04-28 23:44:37 +03:00
|
|
|
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
|
|
|
|
# be specifying the version(s) of Mercurial they are tested with, or
|
|
|
|
# leave the attribute unspecified.
|
2016-08-23 18:26:08 +03:00
|
|
|
testedwith = 'ships-with-hg-core'
|
2011-05-12 22:14:42 +04:00
|
|
|
|
|
|
|
@command('purge|clean',
|
|
|
|
[('a', 'abort-on-err', None, _('abort if an error occurs')),
|
|
|
|
('', 'all', None, _('purge ignored files too')),
|
2013-11-08 05:24:14 +04:00
|
|
|
('', 'dirs', None, _('purge empty directories')),
|
|
|
|
('', 'files', None, _('purge files')),
|
2011-05-12 22:14:42 +04:00
|
|
|
('p', 'print', None, _('print filenames instead of deleting them')),
|
|
|
|
('0', 'print0', None, _('end filenames with NUL, for use with xargs'
|
|
|
|
' (implies -p/--print)')),
|
|
|
|
] + commands.walkopts,
|
|
|
|
_('hg purge [OPTION]... [DIR]...'))
|
2008-05-12 20:37:07 +04:00
|
|
|
def purge(ui, repo, *dirs, **opts):
|
2009-01-05 20:48:20 +03:00
|
|
|
'''removes files not tracked by Mercurial
|
2008-05-12 20:37:07 +04:00
|
|
|
|
2009-07-26 03:59:28 +04:00
|
|
|
Delete files not known to Mercurial. This is useful to test local
|
|
|
|
and uncommitted changes in an otherwise-clean source tree.
|
2008-05-12 20:37:07 +04:00
|
|
|
|
2013-11-08 05:24:14 +04:00
|
|
|
This means that purge will delete the following by default:
|
2009-07-23 02:25:34 +04:00
|
|
|
|
2010-04-22 12:24:49 +04:00
|
|
|
- Unknown files: files marked with "?" by :hg:`status`
|
2009-07-26 03:59:28 +04:00
|
|
|
- Empty directories: in fact Mercurial ignores directories unless
|
|
|
|
they contain files under source control management
|
2009-07-23 02:25:34 +04:00
|
|
|
|
2008-05-12 20:37:07 +04:00
|
|
|
But it will leave untouched:
|
2009-07-23 02:25:34 +04:00
|
|
|
|
|
|
|
- Modified and unmodified tracked files
|
|
|
|
- Ignored files (unless --all is specified)
|
2010-04-22 12:24:49 +04:00
|
|
|
- New files added to the repository (with :hg:`add`)
|
2008-05-12 20:37:07 +04:00
|
|
|
|
2013-11-08 05:24:14 +04:00
|
|
|
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.
|
|
|
|
|
2008-05-12 20:37:07 +04:00
|
|
|
If directories are given on the command line, only files in these
|
|
|
|
directories are considered.
|
|
|
|
|
2009-07-26 03:59:28 +04:00
|
|
|
Be careful with purge, as you could irreversibly delete some files
|
|
|
|
you forgot to add to the repository. If you only want to print the
|
|
|
|
list of files that this program would delete, use the --print
|
|
|
|
option.
|
2008-05-12 20:37:07 +04:00
|
|
|
'''
|
2016-05-17 00:21:39 +03:00
|
|
|
act = not opts.get('print')
|
2008-06-27 03:44:54 +04:00
|
|
|
eol = '\n'
|
2016-05-17 00:21:39 +03:00
|
|
|
if opts.get('print0'):
|
2008-06-27 03:44:54 +04:00
|
|
|
eol = '\0'
|
|
|
|
act = False # --print0 implies --print
|
2016-05-17 00:21:39 +03:00
|
|
|
removefiles = opts.get('files')
|
|
|
|
removedirs = opts.get('dirs')
|
2013-11-08 05:24:14 +04:00
|
|
|
if not removefiles and not removedirs:
|
|
|
|
removefiles = True
|
|
|
|
removedirs = True
|
2007-03-06 23:45:47 +03:00
|
|
|
|
|
|
|
def remove(remove_func, name):
|
|
|
|
if act:
|
|
|
|
try:
|
2009-01-03 00:53:33 +03:00
|
|
|
remove_func(repo.wjoin(name))
|
2008-10-28 21:25:26 +03:00
|
|
|
except OSError:
|
2008-06-27 03:44:54 +04:00
|
|
|
m = _('%s cannot be removed') % name
|
2016-05-17 00:21:39 +03:00
|
|
|
if opts.get('abort_on_err'):
|
2015-10-08 22:55:45 +03:00
|
|
|
raise error.Abort(m)
|
2008-06-27 03:44:54 +04:00
|
|
|
ui.warn(_('warning: %s\n') % m)
|
2007-03-06 23:45:47 +03:00
|
|
|
else:
|
|
|
|
ui.write('%s%s' % (name, eol))
|
|
|
|
|
2011-06-19 01:52:51 +04:00
|
|
|
match = scmutil.match(repo[None], dirs, opts)
|
2014-08-21 02:07:25 +04:00
|
|
|
if removedirs:
|
|
|
|
directories = []
|
|
|
|
match.explicitdir = match.traversedir = directories.append
|
2016-05-17 00:21:39 +03:00
|
|
|
status = repo.status(match=match, ignored=opts.get('all'), unknown=True)
|
2007-03-06 23:45:47 +03:00
|
|
|
|
2013-11-08 05:24:14 +04:00
|
|
|
if removefiles:
|
2014-10-03 21:38:43 +04:00
|
|
|
for f in sorted(status.unknown + status.ignored):
|
2014-02-25 05:00:21 +04:00
|
|
|
if act:
|
2013-11-08 05:24:14 +04:00
|
|
|
ui.note(_('removing file %s\n') % f)
|
2014-08-02 12:45:21 +04:00
|
|
|
remove(util.unlink, f)
|
2013-11-08 05:24:14 +04:00
|
|
|
|
|
|
|
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)
|