hgext/purge.py
author Petr Kodl <petrkodl@gmail.com>
Thu, 09 Oct 2008 10:29:47 -0400
changeset 7118 619ebf82cef2
parent 6762 f67d1468ac50
child 7280 810ca383da9c
permissions -rw-r--r--
Take advantage of fstat calls clustering per directory if OS support it. util module implements two versions of statfiles function _statfiles calls lstat per file _statfiles_clustered takes advantage of optimizations in osutil.c, stats all files in directory at once when new directory is hit and caches the results util.statfiles dispatches to appropriate version during module loading The speedup on directory tree with 2k directories and 63k files is about factor of 1.8 (1.3s -> 0.8s for hg diff - hg startup overhead about .2s) At this point only Win32 now benefit from this patch. Rest of OSes use the non clustered implementation.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2364
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
     1
# Copyright (C) 2006 - Marco Barisione <marco@barisione.org>
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
     2
#
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
     3
# This is a small extension for Mercurial (http://www.selenic.com/mercurial)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
     4
# that removes files not known to mercurial
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
     5
#
4154
15cd36db4230 Delete the README for purge, putting the useful informations in comments
Emanuele Aina <em@nerd.ocracy.org>
parents: 4153
diff changeset
     6
# This program was inspired by the "cvspurge" script contained in CVS utilities
15cd36db4230 Delete the README for purge, putting the useful informations in comments
Emanuele Aina <em@nerd.ocracy.org>
parents: 4153
diff changeset
     7
# (http://www.red-bean.com/cvsutils/).
15cd36db4230 Delete the README for purge, putting the useful informations in comments
Emanuele Aina <em@nerd.ocracy.org>
parents: 4153
diff changeset
     8
#
15cd36db4230 Delete the README for purge, putting the useful informations in comments
Emanuele Aina <em@nerd.ocracy.org>
parents: 4153
diff changeset
     9
# To enable the "purge" extension put these lines in your ~/.hgrc:
15cd36db4230 Delete the README for purge, putting the useful informations in comments
Emanuele Aina <em@nerd.ocracy.org>
parents: 4153
diff changeset
    10
#  [extensions]
4311
1043e4b27ab9 Move back the purge extension in hgext
Emanuele Aina <em@nerd.ocracy.org>
parents: 4310
diff changeset
    11
#  hgext.purge =
4154
15cd36db4230 Delete the README for purge, putting the useful informations in comments
Emanuele Aina <em@nerd.ocracy.org>
parents: 4153
diff changeset
    12
#
15cd36db4230 Delete the README for purge, putting the useful informations in comments
Emanuele Aina <em@nerd.ocracy.org>
parents: 4153
diff changeset
    13
# For help on the usage of "hg purge" use:
15cd36db4230 Delete the README for purge, putting the useful informations in comments
Emanuele Aina <em@nerd.ocracy.org>
parents: 4153
diff changeset
    14
#  hg help purge
15cd36db4230 Delete the README for purge, putting the useful informations in comments
Emanuele Aina <em@nerd.ocracy.org>
parents: 4153
diff changeset
    15
#
2364
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    16
# This program is free software; you can redistribute it and/or modify
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    17
# it under the terms of the GNU General Public License as published by
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    18
# the Free Software Foundation; either version 2 of the License, or
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    19
# (at your option) any later version.
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    20
#
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    21
# This program is distributed in the hope that it will be useful,
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    22
# but WITHOUT ANY WARRANTY; without even the implied warranty of
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    23
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    24
# GNU General Public License for more details.
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    25
#
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    26
# You should have received a copy of the GNU General Public License
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    27
# along with this program; if not, write to the Free Software
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    28
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    29
6574
76af1dff402a purge: use cmdutil.matchpats
Matt Mackall <mpm@selenic.com>
parents: 6573
diff changeset
    30
from mercurial import util, commands, cmdutil
4121
d250076824e3 Use the mercurial i18n infrastructure in the purge extension
Emanuele Aina <em@nerd.ocracy.org>
parents: 4120
diff changeset
    31
from mercurial.i18n import _
2364
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    32
import os
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    33
6573
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    34
def purge(ui, repo, *dirs, **opts):
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    35
    '''removes files not tracked by mercurial
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    36
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    37
    Delete files not known to mercurial, this is useful to test local and
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    38
    uncommitted changes in the otherwise clean source tree.
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    39
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    40
    This means that purge will delete:
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    41
     - Unknown files: files marked with "?" by "hg status"
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    42
     - Ignored files: files usually ignored by Mercurial because they match
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    43
       a pattern in a ".hgignore" file
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    44
     - Empty directories: in fact Mercurial ignores directories unless they
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    45
       contain files under source control managment
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    46
    But it will leave untouched:
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    47
     - Unmodified tracked files
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    48
     - Modified tracked files
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    49
     - New files added to the repository (with "hg add")
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    50
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    51
    If directories are given on the command line, only files in these
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    52
    directories are considered.
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    53
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    54
    Be careful with purge, you could irreversibly delete some files you
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    55
    forgot to add to the repository. If you only want to print the list of
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    56
    files that this program would delete use the --print option.
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    57
    '''
44cd348e6529 purge: eliminate dopurge
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    58
    act = not opts['print']
6757
55c71226eceb purge: cleanup
Matt Mackall <mpm@selenic.com>
parents: 6754
diff changeset
    59
    eol = '\n'
55c71226eceb purge: cleanup
Matt Mackall <mpm@selenic.com>
parents: 6754
diff changeset
    60
    if opts['print0']:
55c71226eceb purge: cleanup
Matt Mackall <mpm@selenic.com>
parents: 6754
diff changeset
    61
        eol = '\0'
55c71226eceb purge: cleanup
Matt Mackall <mpm@selenic.com>
parents: 6754
diff changeset
    62
        act = False # --print0 implies --print
2364
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    63
4153
af72395580e8 Delete the Purge class, refactoring Purge.purge() in dopurge()
Emanuele Aina <faina.mail@tiscali.it>
parents: 4152
diff changeset
    64
    def remove(remove_func, name):
af72395580e8 Delete the Purge class, refactoring Purge.purge() in dopurge()
Emanuele Aina <faina.mail@tiscali.it>
parents: 4152
diff changeset
    65
        if act:
af72395580e8 Delete the Purge class, refactoring Purge.purge() in dopurge()
Emanuele Aina <faina.mail@tiscali.it>
parents: 4152
diff changeset
    66
            try:
af72395580e8 Delete the Purge class, refactoring Purge.purge() in dopurge()
Emanuele Aina <faina.mail@tiscali.it>
parents: 4152
diff changeset
    67
                remove_func(os.path.join(repo.root, name))
af72395580e8 Delete the Purge class, refactoring Purge.purge() in dopurge()
Emanuele Aina <faina.mail@tiscali.it>
parents: 4152
diff changeset
    68
            except OSError, e:
6757
55c71226eceb purge: cleanup
Matt Mackall <mpm@selenic.com>
parents: 6754
diff changeset
    69
                m = _('%s cannot be removed') % name
55c71226eceb purge: cleanup
Matt Mackall <mpm@selenic.com>
parents: 6754
diff changeset
    70
                if opts['abort_on_err']:
55c71226eceb purge: cleanup
Matt Mackall <mpm@selenic.com>
parents: 6754
diff changeset
    71
                    raise util.Abort(m)
55c71226eceb purge: cleanup
Matt Mackall <mpm@selenic.com>
parents: 6754
diff changeset
    72
                ui.warn(_('warning: %s\n') % m)
4153
af72395580e8 Delete the Purge class, refactoring Purge.purge() in dopurge()
Emanuele Aina <faina.mail@tiscali.it>
parents: 4152
diff changeset
    73
        else:
af72395580e8 Delete the Purge class, refactoring Purge.purge() in dopurge()
Emanuele Aina <faina.mail@tiscali.it>
parents: 4152
diff changeset
    74
            ui.write('%s%s' % (name, eol))
4151
337010e50dcd Use nested functions instead of object methods
Emanuele Aina <faina.mail@tiscali.it>
parents: 4150
diff changeset
    75
4153
af72395580e8 Delete the Purge class, refactoring Purge.purge() in dopurge()
Emanuele Aina <faina.mail@tiscali.it>
parents: 4152
diff changeset
    76
    directories = []
6582
5acbdd3941c4 walk: remove remaining users of cmdutils.matchpats
Matt Mackall <mpm@selenic.com>
parents: 6574
diff changeset
    77
    match = cmdutil.match(repo, dirs, opts)
6588
10c23c1d5f33 walk: use match.dir in statwalk
Matt Mackall <mpm@selenic.com>
parents: 6582
diff changeset
    78
    match.dir = directories.append
6754
0b700faaef32 purge: use status
Matt Mackall <mpm@selenic.com>
parents: 6746
diff changeset
    79
    status = repo.status(match=match, ignored=opts['all'], unknown=True)
4147
691f9168a815 Make the purge extension use the statwalk walker from the dirstate object
Emanuele Aina <faina.mail@tiscali.it>
parents: 4121
diff changeset
    80
6762
f67d1468ac50 util: add sort helper
Matt Mackall <mpm@selenic.com>
parents: 6757
diff changeset
    81
    for f in util.sort(status[4] + status[5]):
6754
0b700faaef32 purge: use status
Matt Mackall <mpm@selenic.com>
parents: 6746
diff changeset
    82
        ui.note(_('Removing file %s\n') % f)
0b700faaef32 purge: use status
Matt Mackall <mpm@selenic.com>
parents: 6746
diff changeset
    83
        remove(os.remove, f)
4147
691f9168a815 Make the purge extension use the statwalk walker from the dirstate object
Emanuele Aina <faina.mail@tiscali.it>
parents: 4121
diff changeset
    84
6762
f67d1468ac50 util: add sort helper
Matt Mackall <mpm@selenic.com>
parents: 6757
diff changeset
    85
    for f in util.sort(directories)[::-1]:
4463
a73cf208b2a0 purge: add --include and --exclude options
Emanuele Aina <em@nerd.ocracy.org>
parents: 4311
diff changeset
    86
        if match(f) and not os.listdir(repo.wjoin(f)):
4153
af72395580e8 Delete the Purge class, refactoring Purge.purge() in dopurge()
Emanuele Aina <faina.mail@tiscali.it>
parents: 4152
diff changeset
    87
            ui.note(_('Removing directory %s\n') % f)
af72395580e8 Delete the Purge class, refactoring Purge.purge() in dopurge()
Emanuele Aina <faina.mail@tiscali.it>
parents: 4152
diff changeset
    88
            remove(os.rmdir, f)
2364
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    89
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
    90
cmdtable = {
4695
c3da7b6cc975 purge: add the clean alias inspired by git-clean and svn-clean
Emanuele Aina <em@nerd.ocracy.org>
parents: 4691
diff changeset
    91
    'purge|clean':
2382
b429566d1994 Make indentation of purge's cmdtable match to mercurial/commands.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2381
diff changeset
    92
        (purge,
b429566d1994 Make indentation of purge's cmdtable match to mercurial/commands.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2381
diff changeset
    93
         [('a', 'abort-on-err', None, _('abort if an error occurs')),
4691
ca4971347e0a purge: don't delete ignored files if --all is not specified
Emanuele Aina <em@nerd.ocracy.org>
parents: 4516
diff changeset
    94
          ('',  'all', None, _('purge ignored files too')),
2382
b429566d1994 Make indentation of purge's cmdtable match to mercurial/commands.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2381
diff changeset
    95
          ('p', 'print', None, _('print the file names instead of deleting them')),
b429566d1994 Make indentation of purge's cmdtable match to mercurial/commands.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2381
diff changeset
    96
          ('0', 'print0', None, _('end filenames with NUL, for use with xargs'
4463
a73cf208b2a0 purge: add --include and --exclude options
Emanuele Aina <em@nerd.ocracy.org>
parents: 4311
diff changeset
    97
                                  ' (implies -p)')),
5147
c80af96943aa refactor options from cmdtable
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 4957
diff changeset
    98
         ] + commands.walkopts,
2382
b429566d1994 Make indentation of purge's cmdtable match to mercurial/commands.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2381
diff changeset
    99
         _('hg purge [OPTION]... [DIR]...'))
2364
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
   100
}