annotate purge.py @ 2369:9da3dd62c827

Purge.from_command is now a function called purge
author demian@gaudron.lan
date Tue, 16 May 2006 13:37:48 +0200
parents f368a1c302d5
children de893ad6bd17
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2364
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
1 #!/usr/bin/env python
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
2 #
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
3 # Copyright (C) 2006 - Marco Barisione <marco@barisione.org>
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
4 #
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
5 # This is a small extension for Mercurial (http://www.selenic.com/mercurial)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
6 # that removes files not known to mercurial
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
7 #
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
8 # This program is free software; you can redistribute it and/or modify
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
9 # it under the terms of the GNU General Public License as published by
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
10 # the Free Software Foundation; either version 2 of the License, or
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
11 # (at your option) any later version.
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
12 #
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
13 # This program is distributed in the hope that it will be useful,
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
16 # GNU General Public License for more details.
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
17 #
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
18 # You should have received a copy of the GNU General Public License
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
19 # along with this program; if not, write to the Free Software
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
20 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
21
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
22 from mercurial import hg, util
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
23 import os
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
24
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
25 class Purge(object):
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
26 def __init__(self, act=True, abort_on_err=False):
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
27 self._repo = None
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
28 self._ui = None
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
29 self._hg_root = None
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
30 self._act = act
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
31 self._abort_on_err = abort_on_err
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
32
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
33 def purge(self, ui, repo, paths=None):
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
34 self._repo = repo
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
35 self._ui = ui
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
36 self._hg_root = self._split_path(repo.root)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
37
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
38 if not paths:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
39 paths = [repo.root]
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
40
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
41 for path in paths:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
42 path = os.path.abspath(path)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
43 for root, dirs, files in os.walk(path, topdown=False):
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
44 if '.hg' in self._split_path(root):
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
45 # Skip files in the .hg directory.
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
46 # Note that if the repository is in a directory
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
47 # called .hg this command does not work.
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
48 continue
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
49 for name in files:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
50 self._remove_file(os.path.join(root, name))
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
51 if not os.listdir(root):
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
52 # Remove this directory if it is empty.
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
53 self._remove_dir(root)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
54
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
55 self._repo = None
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
56 self._ui = None
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
57 self._hg_root = None
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
58
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
59 def _error(self, msg):
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
60 if self._abort_on_err:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
61 raise util.Abort(msg)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
62 else:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
63 ui.warn('warning: ' + msg + '\n')
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
64
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
65 def _remove_file(self, name):
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
66 relative_name = self._relative_name(name)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
67 # dirstate.state() requires a path relative to the root
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
68 # directory.
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
69 if self._repo.dirstate.state(relative_name) != '?':
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
70 return
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
71 if self._ui.verbose:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
72 self._ui.status(name + '\n')
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
73 if self._act:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
74 try:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
75 os.remove(name)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
76 except OSError, e:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
77 error('"%s" cannot be removed' % name)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
78
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
79 def _remove_dir(self, name):
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
80 if self._ui.verbose:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
81 self._ui.status(name + '\n')
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
82 if self._act:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
83 try:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
84 os.rmdir(name)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
85 except OSError, e:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
86 error('"%s" cannot be removed' % name)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
87
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
88 def _relative_name(self, name):
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
89 splitted_path = self._split_path(name)[len(self._hg_root):]
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
90 return self._join_path(splitted_path)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
91
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
92 def _split_path(self, path):
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
93 ret = []
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
94 while True:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
95 head, tail = os.path.split(path)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
96 if tail:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
97 ret.append(tail)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
98 if head == path:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
99 ret.append(head)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
100 break
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
101 path = head
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
102 ret.reverse()
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
103 return ret
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
104
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
105 def _join_path(self, splitted_path):
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
106 ret = ''
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
107 for part in splitted_path:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
108 if ret:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
109 ret = os.path.join(ret, part)
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
110 else:
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
111 ret = part
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
112 return ret
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
113
2369
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
114
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
115 def purge(ui, repo, *paths, **opts):
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
116 '''removes files not tracked by mercurial
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
117
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
118 Delete files not known to mercurial, this is useful to test local and
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
119 uncommitted changes in the otherwise clean source tree.
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
120
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
121 This means that purge will delete:
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
122 - Unknown files: files marked with "?" by "hg status"
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
123 - Ignored files: files usually ignored by Mercurial because they match a
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
124 pattern in a ".hgignore" file
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
125 - Empty directories: infact Mercurial ignores directories unless they
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
126 contain files under source control managment
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
127 But it will leave untouched:
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
128 - Unmodified tracked files
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
129 - Modified tracked files
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
130 - New files added to the repository (with "hg add")
2364
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
131
2369
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
132 If names are given, only files matching the names are considered, else
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
133 all files in the repository directory are considered.
2364
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
134
2369
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
135 Be careful with purge, you could irreversibly delete some files you
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
136 forgot to add to the repository. If you only want to print the list of
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
137 files that this program would delete use the -vn options.
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
138 '''
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
139 act = True
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
140 if opts['nothing']:
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
141 act = False
2364
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
142
2369
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
143 abort_on_err = True
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
144 if not opts['abort_on_err']:
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
145 abort_on_err = False
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
146
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
147 p = Purge(act, abort_on_err)
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
148 p.purge(ui, repo, paths)
2364
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
149
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
150
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
151 cmdtable = {
2369
9da3dd62c827 Purge.from_command is now a function called purge
demian@gaudron.lan
parents: 2364
diff changeset
152 'purge': (purge,
2364
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
153 [('a', 'abort-on-err', None, 'abort if an error occurs'),
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
154 ('n', 'nothing', None, 'do nothing on files, useful with --verbose'),
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
155 ],
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
156 'hg purge [OPTIONS] [NAME]')
f368a1c302d5 Initial commit
demian@gaudron.lan
parents:
diff changeset
157 }